终极思想
- 如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
- 如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面【阻塞的只是当前路径,并不阻塞其它路径的代码】的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
示例一
代码
function testSometing() {
console.log("testSomething");
return "return testSomething";
}
async function testAsync() {
console.log("testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const testFn1 = await testSometing();
console.log(testFn1);
const testFn2 = await testAsync();
console.log(testFn2);
console.log('test end...');
}
test();
var promiseFn = new Promise((resolve)=> {
console.log("promise START...");
resolve("promise RESOLVE");
});
promiseFn.then((val)=> console.log(val));
console.log("===END===")
运行结果
运行解说
- 首先test()打印出test start...
- 然后 testFn1 = await testSomething(); 的时候,会先执行testSometing()这个函数打印出“testSometing”的字符串。
- testAsync()执行完毕返回resolve,之后await会让出线程就会去执行后面的,触发promiseFn打印出“promise START...”。
- 接下来会把返回的Promiseresolve("promise RESOLVE")放入Promise队列(Promise的Job Queue),继续执行打印 “=== END ===”。
- 等本轮事件循环执行结束后,又会跳回到async函数中(test()函数),等待之前await 后面表达式的返回值,因为testSometing() 不是async函数,所以返回的是一个字符串“return``testSometing”。
- test()函数继续执行,执行到testFn2(),再次跳出test()函数,打印出“testAsync”,此时事件循环就到了Promise的队列,执行promiseFn.then((val)=> console.log(val));打印出“promise RESOLVE”。
- 之后和前面一样 又跳回到test函数继续执行console.log(testFn2)的返回值,打印出“hello async”。
- 最后打印“test end...”。
示例二
加点料,让testSomething()变成async
代码
async function testSometing() {
console.log("testSomething");
return "return testSomething";
}
async function testAsync() {
console.log("testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const testFn1 = await testSometing();
console.log(testFn1);
const testFn2 = await testAsync();
console.log(testFn2);
console.log('test end...');
}
test();
var promiseFn = new Promise((resolve)=> {
console.log("promise START...");
resolve("promise RESOLVE");
});
promiseFn.then((val)=> console.log(val));
console.log("===END===")
运行结果
运行解说
和上一个例子比较发现promiseFn.then((val)=> console.log(val)); 先于console.log(testFn1) 执行。
原因是因为现在的版本async函数会被await resolve,
补充
function testSometing() {
console.log("testSomething");
return "return testSomething";
}
console.log(Object.prototype.toString.call(testSometing)) // [object Function]
console.log(Object.prototype.toString.call(testSometing())) // [object String]
async function testSometing() {
console.log("testSomething");
return "return testSomething";
}
console.log(Object.prototype.toString.call(testSometing)) // [object AsyncFunction]
console.log(Object.prototype.toString.call(testSometing())) // [object Promise]
testSomething()已经是async函数,返回的是一个Promise对象需要等它 resolve 后将当前Promise 推入队列,随后先清空调用栈,所以会"跳出" test() 函数执行后续代码,随后才开始执行该 Promise。