知识点_Promise_async与await
之前有这样一个疑问,我在函数1中使用await等待异步执行,在函数2中调用函数1,那函数2中的同步代码会等待函数1执行完毕再执行吗?若是返回值不是一个promise,async函数将会将值包装为一个Promise。如下例调用listChenge函数,是先打印111呢还是先打印222呢?注意点await操作符只能在async函数中使用,否则会抛出异常;async函数的执行,等待promise执行完毕
async与await
作用
使用async/await可以编写形式同步的代码来处理异步流程;
概念
await
-
注意点:await操作符只能在async函数中使用,否则会抛出异常;
‘await’ is only allowed within async functions
-
语法
[返回值] = await 表达式表达式可以是一个 Promise对象 或者 任意要等待的值;
[1]表达式为Promise对象 —> 返回值为
Promise的处理结果(也就是传入then方法中的数据);function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); } async function listChenge(){ const res = await this.resolveAfter2Seconds(1) console.log('结果', res) // 1 }[2]表达式为非Promise对象 —> 返回值为值本身
async listChenge(){ const res = await 1 console.log('结果', res) // 1 } -
await表达式会立即
暂停当前 async 函数的执行,让引擎继续执行后面的同步代码,等到所有同步代码执行完毕后,将 await 后面的代码包装成微任务,在微任务队列中等待执行- promise-fulfilled—>继续执行async function;
- promise-rejected—>将Prmoise的异常原因抛出;
async函数
-
定义:使用async关键字声明的函数被称为async函数;
-
语法:
async function 函数名(){} -
返回值:
[1] 若是没有返回值,默认值为undefined[2] 若是存在返回值
-
若是返回值为promise对象,直接返回
-
若是返回值不是一个promise,async函数将会将值包装为一个Promise
async function test(){ return 222 } // 等价于 async function test(){ return new Promise(){ resolve(222)} }
-
async与await结合使用
- async中存在0个或者多个await;
- await表达式会立即
暂停当前 async 函数的执行,让引擎继续执行后面的同步代码,等到所有同步代码执行完毕后,将 await 后面的代码包装成微任(Promise),在微任务队列中等待执行,只有当其等待的基于 promise 的异步操作被兑现或被拒绝之后才会恢复进程。promise 的解决值会被当作该 await 表达式的返回值
现在通过下面代码真正理解一下awiat代码的执行流程
console.log('Script start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
async function asyncFunc() {
console.log('2');
await Promise.resolve(); // 等待一个立即解决的Promise
console.log('4');
}
asyncFunc();
Promise.resolve().then(() => {
console.log('3');
});
console.log('Script end');
// 输出顺序:
// Script start
// 2. Inside asyncFunc - before await
// Script end
// 3. Promise.then (Microtask) <- 微任务1
// 4. Inside asyncFunc - after await (Microtask) <- 微任务2
// setTimeout (Macrotask) <- 宏任务
上述代码3和4哪个先打印出来呢?
- ‘Script start’
- 将setTimeout加入宏任务
- ‘2’ 暂停async函数的执行 等待所有同步代码执行完毕( 此时没有将这里的微任务加入微任务队列)
- 将Promise微任务加入微任务队列
- ‘Script end’
- 此时同步任务执行完毕 将await后面的代码包装成微任务加入队列
- 执行微任务 遵循先入先出 所以 先打印3再打印4
- 执行宏任务 ‘setTimeout’
- 总结: 执行顺序为 ‘Script start’ ‘2’ ‘Script end’ ‘3’ ‘4’ ‘setTimeout’
思考题
async function awaitMethod(){
const res = await new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('111')
resolve()
},5000)
})
console.log('333')
}
function listChenge(){
this.awaitMethod()
console.log('222')
}
-
答案:先打印222,等待5秒打印111,333
-
执行步骤:
[1] 调用awaitMethod方法,里面存在await中断awaitMethod方法的执行
[2] 打印222
[3] 5秒钟之后打印111,Promise结束,打印333
const res = await new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('111')
resolve()
},5000)
})
console.log('333')
}
async function listChenge(){
await this.awaitMethod()
console.log('222')
}
listChenge()
答案: 等待5s之后打印111,333,222
更多推荐


所有评论(0)