同步和异步(promise,async,await)
(promise,async,await),宏任务、微任务
1、同步和异步
同步是指代码在一帧内执行;异步是指需要等待某个内容完成后才执行。
console.log("aaa");
for(var i=0;i<1000000000;i++){
}
console.log("bbb");//同步
同步 停止等待运行结束,继续后续的运行。
console.log("aa");
setTimeout(function(){
console.log("bb");
},5000)
console.log("cc"); //异步
异步操作就是需要等待一个内容完成后继续执行后面的内容,但是不能将后面的内容写在等待函数外,否则就会同时执行两个。
常见异步的事件:
load事件、setTimeout、setInteral、requestAnimationFrame()
如果大量使用onload以及onclick等代码容易造成回调地狱。此时就可以使用promise。
2、promise
处理异步模式,将异步模式摊开来处理。
var p=new Promise(function(resolve,reject){
var img=new Image();
img.src="./img/17.jpg";
img.onload=function(){
resolve(img);
}
img.onerror=function(){
reject(img.src+"地址错误");
}
})
p.then(function(a){
console.log(a);//执行resolve执行这个函数
},function(b){
console.log(b);//执行reject执行这个函数
})
promise中的函数有两个参数,两个参数都是函数,如上述代码,一个为resolve当加载成功时调用,一个为reject当加载失败时调用。
Promise中有一个then的方法,它里面也有两个参数,第一个参数是执行resolve执行这个函数,第二个参数是执行reject这个函数。
p.then(function(a){
console.log(a);//执行resolve执行这个函数
}).catch(function(b){
console.log(b);//执行reject执行这个函数
})
也可以用then和catch写用法使用一样的,在then调用的函数中也可以使用函数return的返回值再次调用then
new Promise(function (resolve, reject) {
var img1 = new Image();
img1.src = "./img/3-.jpg";
img1.onload = function () {
resolve(img1);
};
})
.then(function (img) {
arr.push(img);
return new Promise(function (resolve, reject) {
var img2 = new Image();
img2.src = "./img/4-.jpg";
img2.onload = function () {
resolve(img2);
};
});
})
.then(function (img) {
arr.push(img);
return new Promise(function (resolve, reject) {
var img3 = new Image();
img3.src = "./img/5-.jpg";
img3.onload = function () {
resolve(img3);
};
});
});
Promise中提供了一个all的方法,他可以统一处理所有数组,并且返回一个列表。
Promise.all(arr).then(function(list){
list.forEach(item=>{
console.log(item.src);
})
Promise中还有一个race方法
Promise.race(arr).then(function(img){
console.log(img);//异步列表中谁最先完成就执行谁
Promise是否可以连续then
var p=new Promise(function(resolve,reject){
resolve(1);
});
p.then(function(a){
console.log(a);// 如果在这里没有return Promise对象就会继续执行下一个then中的内容
// 下一个then中对应的执行对象仍然是当前promise对象
});
p.then(function(){
})
代码执行的顺序
在promise对象方法中then和catch方法本身都是异步的
在promise对象中出来then和catch是异步之外,其他的都是同步的
console.log("a");
new Promise(function(resolve,reject){
console.log("b");
resolve(1);
console.log("c");
}).then(function(a){
console.log("d");
}).then(function(){
console.log("e");
})
console.log("f");
//abcfde
promise中resolve和reject执行的干扰问题
只能执行一个,具有排他性
function getImage(src) {
return new Promise(function (resolve, reject) {
var img1 = new Image();
img1.src = src;
img1.onload = function () {
resolve(img1);
reject(img1.src+"地址错误");
};
});
}
PromiseStatus 分为3个
pending 准备状态
resolved 执行resolve的状态
rejected 执行reject的状态
3、async和await
async函数执行后返回一个promise对象
await只能写在async函数中
await只能处理promise对象的异步等待
async函数中使用return返回的内容可以通过then来获取
function getImage(src) {
return new Promise(function (resolve, reject) {
var img1 = new Image();
img1.src = src;
img1.onload = function () {
resolve(img1);
};
});
}
async function loadImages(){
var arr=[];
for(var i=3;i<30;i++){ await getImage("./img/"+i+"-.jpg").then(function(img){
arr.push(img);
})
4、宏任务、微任务
异步和同步都是在完成任务列的内容
同步任务逐条进行
异步任务存在固定时间与非固定时间
setTimeout,setInterval,requestAnimationFrame,promise都是固定时间
加载文件和图片都是非固定时间
setTimeout setInterval是宏任务
Promise 微任务
宏任务指将当前的任务挪至到下一个任务列的最顶端执行
微任务指将当前任务的内容挪至到当前任务列的最低端执行
Promise.resolve().then(function(){
setTimeout(function(){
console.log("b");
},0)
})
setTimeout(function(){
Promise.resolve().then(function(){
console.log("a");
})
},0)
宏任务里的微任务执行优先微任务里的宏任务;
微任务里的微任务比微任务优先
理解以下代码运行顺序
console.log(1);//1
new Promise(function (res, rej) {
console.log(2);//2
res();
})
.then(function () {
console.log(3);//5
Promise.resolve().then(function () {
console.log(5);//6
setTimeout(function () {
console.log(6);//15
Promise.resolve().then(function () {
console.log(7);//16
});
setTimeout(function () {
console.log(8);//18
}, 0);
}, 0);
});
})
.then(function () {
console.log(4);//7
});
setTimeout(function () {
console.log(9);//8
new Promise(function (res) {
res();
console.log(10);//9
}).then(function () {
console.log(11);//10
});
});
Promise.resolve().then(function () {
setTimeout(function () {
Promise.resolve().then(function () {
console.log(12);//14
});
console.log(13);//13
}, 0);
});
setTimeout(function () {
setTimeout(function () {
setTimeout(function () {
Promise.resolve().then(function () {
console.log(14);//20
});
console.log(15);//19
}, 0);
console.log(16);//17
}, 0);
console.log(17);//11
}, 0);
console.log(18);//3
new Promise(function (res) {
console.log(19);//4
setTimeout(function () {
console.log(20);//12
}, 0);
});
推荐阅读
-
同步和异步(promise,async,await)
-
VUE:使用async和await实现axios同步请求
-
axios 通过async和await实现同步
-
vue中使用async、await和promise实现异步API的同步调用
-
使用 async 和 await,实现 fetch 同步请求
-
vue 使用 async 和 await 实现异步 axios 同步化(实战案例:数据异步校验通过后,再执行保存)
-
vue 中使用 async/await 将 axios 异步请求同步化处理
-
微信小程序 ———— 异步请求中使用async/await实现同步请求
-
使用async和await优化异步事件
-
ES6(7)之Async和await