async/await
前端
0
361
0
发表于: 2020-07-21 15:34:32
简介: 暂无~
async 函数的返回值
下面解释 async 关键字做了什么:
- 被 async 操作符修饰的函数必然返回一个 Promise
- 当 async 函数返回一个值时,Promise 的 resolve 方法负责传递这个值
- 当 async 函数抛出异常时,Promise 的 reject 方法会传递这个异常值
await 操作符做了什么
- await 后的值 v 会被转换为 Promise
- 即使 v 是一个已经
fulfilled
的 Promise,还是会新建一个 Promise,并在这个新 Promise 中resolve(v)
await v
后续的代码的执行类似于传入then()
中的回调
async function foo() {
await bar()
console.log('foo')
}
async function bar() {
console.log('bar');
}
foo()
new Promise(resolve => {
console.log('p1');
resolve();
}).then(function () {
console.log('p2')
})
//chrome 84环境下结果:bar,p1,foo,p2
根据提示
async function async1(){
await async2()
console.log('async1 end')
}
等价于
async function async1() {
return new Promise(resolve => {
resolve(async2())
}).then(() => {
console.log('async1 end')
})
}
RESOLVE(non-thenable)
如果await 后面直接跟的为一个变量,比如:await 1;这种情况的话相当于直接把await后面的代码注册为一个微任务,可以简单理解为promise.then(await下面的代码)。然后跳出async1函数,执行其他代码,当遇到promise函数的时候,会注册promise.then()函数到微任务队列,注意此时微任务队列里面已经存在await后面的微任务。
async function foo() {
console.log('foo')
// var res = await 1
// console.log('foo_end')
// 上两条代码等价于
return new Promise(resolve => {
resolve(1)
}).then(() => {
console.log('foo_end')
})
}
async function bar() { }
foo()
new Promise(function (resolve) {
console.log('p1')
resolve();
}).then(function () {
console.log('p2')
})
//foo,p1,foo_end,p2
RESOLVE(thenable)
async2() 返回一个 promise, 是一个 thenable 对象,RESOLVE(thenable) 并不等于 Promise.resolve(thenable) ,而 RESOLVE(non-thenable) 等价于 Promise.resolve(non-thenable),下面几个例子可证明:
let p1 = new Promise(resolve => {
resolve(1)
})
p1.then(() => {
console.log(2)
})
let p2 = Promise.resolve().then(res => {
console.log(3)
})
p2.then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
//2,3,4,5
// let p1 = new Promise(resolve => {
// resolve(1)
// })
// 等价于
let p1 = Promise.resolve(1)
p1.then(() => {
console.log(2)
})
let p2 = Promise.resolve().then(res => {
console.log(3)
})
p2.then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
//2,3,4,5
let p1 = new Promise(resolve => {
let p3 = Promise.resolve()
resolve(p3)
})
p1.then(() => {
console.log(2)
})
let p2 = Promise.resolve().then(res => {
console.log(3)
})
p2.then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
//3,4,2,5
let p1 = new Promise(resolve => {
let p3 = Promise.resolve()
resolve(p3)
})
p1.then(() => {
console.log(2)
})
let p2 = Promise.resolve().then(res => {
console.log(3)
})
p2.then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
//3,4,2,5
let p1 = new Promise(resolve => {
let p3 = Promise.resolve()
// resolve(p3)
// 等价于
Promise.resolve().then(() => {
Promise.resolve(p3).then(() => {
resolve();
})
})
})
p1.then(() => {
console.log(2)
})
let p2 = Promise.resolve().then(res => {
console.log(3)
})
p2.then(() => {
console.log(4)
}).then(() => {
console.log(5)
})
//3,4,2,5
RESOLVE(thenable) 和 Promise.resolve(thenable)的转换关系
new Promise(resolve=>{
resolve(thenable)
})
会被转换成:
new Promise(resolve => {
Promise.resolve().then(() => {
thenable.then(resolve)
})
})
或者:
new Promise(resolve => {
Promise.resolve().then(() => {
Promise.resolve(thenable).then(() => {
resolve()
})
})
})
await 将直接使用 Promise.resolve()相同语义
原题:
async function foo() {
await bar()
console.log('foo')
}
async function bar() {
console.log('bar');
}
foo()
new Promise(resolve => {
console.log('p1');
resolve();
}).then(function () {
console.log('p2')
})
上述代码在chrome 70会最终编译成:
async function foo() {
// return new Promise(resolve => {
// resolve(bar())
// }).then(() => {
// console.log('foo')
// })
// 上面的代码等价于
return new Promise(resolve => {
Promise.resolve().then(() => {
bar().then(resolve)
})
}).then(() => {
console.log('foo')
})
}
async function bar() {
console.log('bar');
}
foo()
new Promise(resolve => {
console.log('p1');
resolve();
}).then(function () {
console.log('p2')
})
// 结果:p1,bar,p2,foo
而在chrome 73中,会编译成:
async function foo() {
const p = bar()
Promise.resolve(p).then(() => {
console.log('foo')
})
}
async function bar() {
console.log('bar');
}
foo()
new Promise(resolve => {
console.log('p1');
resolve();
}).then(function () {
console.log('p2')
})
//结果:bar,p1,foo,p2
因为await规范的更新,导致了await bar()在chrome 70和chrome 73最终编译成的代码不一样,因此,结果也会不一样,如果不适用await 关键字,直接用原生的Promise语句就不会出现这个问题(因为await的就是promise语法糖,会最终编译成promise语句)。
参考以下文章:
令人费解的 async/await 执行顺序
async await 和 promise微任务执行顺序问题
async/await 原理及执行顺序分析
知乎贺老师的解答
这一次,彻底弄懂 Promise 原理
最后更新于:2021-02-16 21:13:29
欢迎评论留言~
0/400
支持markdownComments | 0 条留言
登录
按时间
按热度
目前还没有人留言~