最近在迭代优化项目,发现自己代码中很多异步的请求,写的很混乱,不清晰。之前也有听说过一些JS处理异步回调的方法,但是没有用到实际开发中,废话不多说。
刚开始我们处理异是用callback,然后用Promise,然后是Generator函数,但是这几种方案都有对应的复杂性,async/await 是 JS 编写异步程序的新方法,建立在Promise之上
一、async是什么?
MDN的描述:
**async function**
声明用于定义一个返回AsyncFunction
对象的异步函数。异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的Promise
返回其结果。但是如果你的代码使用了异步函数,它的语法和结构会更像是标准的同步函数。
也就是说async函数会返回一个Promise对象。
- 如果async函数中是return一个值,这个值就是Promise对象中resolve的值;
- 如果async函数中是throw一个值,这个值就是Promise对象中reject的值。
async的写法
async function imAsync(num) {
if (num > 0) {
return num // 这里相当于resolve(num)
} else {
throw num // 这里相当于reject(num)
}
}
imAsync(1).then(function (v) {
console.log(v); // 1
});
// 注意这里是catch
imAsync(0).catch(function (v) {
console.log(v); // 0
})
promise的写法
function imPromise(num) {
return new Promise(function (resolve, reject) {
if (num > 0) {
resolve(num);
} else {
reject(num);
}
})
}
imPromise(1).then(function (v) {
console.log(v); // 1
})
imPromise(0).then(function (v) {
console.log(v); // 0
})
二、await是什么
MDN的描述
await 表达式会暂停当前
async function
的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行async function
。
await
操作符用于等待一个Promise
对象。它只能在异步函数async function
中使用。
所以 await 等待的不是所有的异步操作,等待的只是Promise。
举个代码
我想下面代码输出 1 2 3
console.log("1");
setTimeout(function () {
console.log("2");
}, 1000);
console.log("3");
promise写法
console.log("1");
function fun(){
return new Promise((resolve,reject)=>{
setTimeout(function () {
console.log("2");
resolve();
}, 1000);
})
}
fun().then(()=>{
console.log("3");
});
async/wait写法
console.log("1");
function fun1(){
return new Promise((resolve,reject)=>{
setTimeout(function () {
console.log("2");
resolve();
}, 1000);
})
}
async function fun2(){
await fun1();
console.log("3");
}
fun2();
await 会将代码执行的权利交给他后面的函数,等到后面这个函数执行完后再执行之后的代码。在这里就是fun1函数。
async/await 的fashion写法IIFE
(async function(){
console.log("1");
await new Promise((resolve,reject)=>{
setTimeout(function () {
console.log(2);
resolve();
}, 1000);
})
console.log("3");
})()
需要注意的是,async/await 是建立在Promise 之上的,await并不是所有函数都会等,await只会等待Promise
// 注意,这是错误的做法
(async function () {
console.log(1);
await setTimeout(function () {
console.log(2);
}, 1000);
console.log(3);
}())
关键点就是得是返回Promise对象的函数才行,不然await等你后面的函数执行完了,见你没返回Promise对象,那他就继续执行了,不管你了。
以上是个人整理和总结,希望对大家有帮助!!!!