await操做符node
async function fun(){
var val = await 20;
console.log(val);
}
fun();
//20
async function bar(){
var val = await Promise.resolve(20);
console.log(val);
}
bar();
//20
复制代码
async函数chrome
async function bar(name){
var subName = await Promise.resolve('fen');
return name + subName;
}
bar('li').then((res)=>{
console.log(res);
});
//lifen
复制代码
new Promise((resolve) => {
resolve();
}).then(() => {
console.log('p1_1')
}).then(() => {
console.log('p1_2')
}).then(() => {
console.log('p1_3')
});
new Promise((resolve) => {
resolve();
}).then(() => {
console.log('p2_1')
}).then(() => {
console.log('p2_2')
}).then(() => {
console.log('p2_3')
});
复制代码
结果以下:segmentfault
p1_1
p2_1
p1_2
p2_2
p1_3
p2_3
复制代码
Promise是基于微任务的(微任务文章点击连接),async/await可视为 Promise 的语法糖,一样基于微任务实现promise
EnquequeJob存放两种类型的任务, 即PromiseResolveThenableJob和PromiseReactionJob, 而且都是属于microtask类型的任务。浏览器
PromiseReactionJob: 能够通俗的理解为promise中的回调函数 PromiseResolveThenableJob(promiseToResolve, thenable, then): 建立和 promiseToResolve 关联的 resolve function 和 reject function。以 then 为调用函数,thenable 为this,resolve function和reject function 为参数调用返回。bash
Promise中resolve一个thenable对象,执行步骤如何? 在 Promise 中 resolve 一个 thenable 对象时,异步
这个过程须要做为一个 job 加入微任务队列,以保证对 then 方法的解析发生在其余上下文代码的解析以后async
let thenable = {
then(resolve, reject) {
console.log('in thenable');
resolve(100);
}
};
var promiseB = new Promise((resolve) => {
console.log('promiseB');
resolve(thenable);
});
//或var promiseB = Promise.resolve(thenable);
var promiseA = new Promise((resolve) => {
console.log('promiseA');
resolve();
});
promiseB.then((res) => {
console.log('out thenable ' + res)
}).then(() => {
console.log('then2')
}).then(() => {
console.log('then3')
});
promiseA.then(() => {
console.log(1);
}).then(() => {
console.log(2)
}).then(() => {
console.log(3)
});
复制代码
结果以下:函数
promiseB
promiseA
in thenable
1
out thenable 100
2
then2
3
then3
复制代码
in thenable 后于 promiseA 而先于 1 输出,同时out thenable 100 在 1 后输出。post
Promise.resolve(thenable)与new Promise(resolve=>(resolve(thenable)))的处理结果一致
正是因为规范中对 thenable 的处理须要在一个微任务中完成,从而致使了第一个 Promise 的后续回调被延后了1个时序
var promiseA = Promise.resolve('promiseA');
var promiseB = new Promise((resolve) => {
resolve(promiseA);
});
//或var promiseB = Promise.resolve(promiseA);
promiseB.then(() => {
console.log('then1')
}).then(() => {
console.log('then2')
}).then(() => {
console.log('then3')
});
promiseA.then(() => {
console.log(1);
}).then(() => {
console.log(2);
}).then(() => {
console.log(3);
});
复制代码
结果
//new Promise
1
2
then1
3
then2
then3
复制代码
//采用或的结构Promise.resolve(promiseA)
then1
1
then2
2
then3
3
复制代码
'then1'输出晚了两个时序。对于参数是一个promise ,resolve(promiseA)究竟如何工做的?
例子中,当promiseB被resolved的时候, 也就是将一个promise(代指A)当成另一个promise(代指B)的resolve参数,会向EnquequeJob插入一个PromiseResolveThenableJob任务。PromiseResolveThenableJob大概作了以下的事情:
() => {
promiseA.then(
resolvePromiseB,
rejectPromiseB
);
}
复制代码
而且当resolvePromiseB执行后, promiseB的状态才变成resolve,也就是B追随A的状态。
async function async1() {
console.log('async1')
await async2();
console.log('async1 end')
}
async function async2() {
console.log('async2');
}
async1();
new Promise(function (resolve) {
console.log('promise')
resolve();
}).then(function () {
console.log(1);
}).then(function () {
console.log(2);
}).then(function () {
console.log(3);
})
复制代码
浏览器chrome76 环境中,结果以下:
//浏览器chrome76
async1
async2
promise
async1 end
1
2
3
复制代码
node环境中,async1 end被推迟了2个时序
//node v10.6.0,
async1
async2
promise
1
2
async1 end
3
复制代码
以浏览器运行结果来转换
function async1(){
console.log('async1 start');
const p = async2();
return Promise.resolve(p).then(() => {
console.log('async1 end')
});
}
function async2(){
console.log('async2');
return Promise.resolve();
}
//其余代码同上
复制代码
参考连接: 使人费解的 async/await 执行顺序