异步
- 同步和异步的区别
同步按照代码顺序执行,遇到耗时任务会阻塞代码的执行;异步遇到耗时任务会将同步代码先执行完,再去执行异步任务 - 手写用Promise加载一张图片
function loadImage(defaultSrc) {
return new Promise((resolve, reject) => {
const image = new Image();
image.src = defaultSrc;
image.onload = function() {
resolve(image)
}
image.onerror = function(error) {
reject(image)
}
document.body.appendChild(image)
})
}
loadImage('default.png')
.then(image => {
setTimeout(function () {
image.src = 'xxx.png'
}, 1000)
})
.catch(err => console.log(err))
- 前端使用异步的场景有哪些
见知识点-应用场景 - 定时器问题,代码如下:
// setTimeout笔试题,写出输出顺序
// 1 3 5 4 2
console.log(1);
setTimeout(function() {
console.log(2);
}, 1000);
console.log(3);
setTimeout(function() {
console.log(4);
}, 0);
console.log(5);
- 手写Promise的实现原理:
见博客:面试重点——promise原理以及实现
知识点
- 单线程和异步
-
js是单线程语言,只能同时做一件事儿
-
浏览器和nodejs已支持启动进程,如web worker
-
js和DOM渲染共用同一个线程,因为js可以修改dom结构
-
遇到等待(网络请求、定时任务)不能卡住
-
需要异步
-
回调callback函数形式
举个例子来区分同步和异步:
// 异步,代码的执行不会被阻塞,1 3 2
console.log(1);
setTimeout(() => console.log(2), 1000);
console.log(3);
// 同步,代码的执行按照书写顺序,会被阻塞 1 2 3
console.log(1);
alert(2)
console.log(3);
- 应用场景
- 网络请求
举个例子:
// 执行顺序 start end data
console.log('start');
$.get('./data.json', function (data) {
console.log(data)
});
console.log('end');
- 定时任务
举个例子:
// 执行顺序 start end wait
console.log('start');
setTimeout(function () {
console.log('wait')
}, 1000);
console.log('end');
- 图片加载
举个例子:
// 图片预加载示例
console.log('start');
var image = new Image();
image.onload = function () {
img.src = 'xxx.png';
}
imgage.src = 'default.png';
document.body.appendChild(image)
console.log('end');
- callback hell和Promise
回调地狱是callback形式嵌套多层时最恶心的,因其结构型似金字塔,又被称为回调金字塔。其形式为
getData(url1, function(data) {
getData(url2, function(data2) {
getData(url3, function(data3) {
// code...
})
})
})
Promise
promise彻底改变了回调地狱中变量难以追踪的这一难题,使得书写形式不再基于回调函数形式,而是采用thenable
形式。但是promise只是将回调函数放到了then中执行,并未改变其回调函数的本质。
举个例子
function getData(url) {
return new Promse((resolve, reject) => {
$.get(url, {
success(data) {
resolve(data)
},
error(err) {
reject(err)
}
})
})
}