在潜入之前,最好注意一些事情。
代码片段的任何读者
let waiting = function () {
return new Promise(resolve => {
console.log('awaiting...');
setTimeout(function () { resolve(); }, 1000);
});
};
let waitingAsync = async function () {
console.log('start...');
await waiting();
console.log('stop...');
};
waitingAsync();
console.log('done...');
可能会误导人们相信输出将是
start...
awaiting...
stop...
done...
done...
而——正如你已经注意到的——在
stop...
.
原因是这waitingAsync();
是对异步函数的调用,而console.log('done...');
只是一个立即执行的正常顺序/同步语句。
问题 1:
waiting
是一个同步函数(因为它没有async
关键字)[?]
答案:
错误。该函数waiting
是同步的——它返回一个 Promise。
问题 2:
为什么done...
完成waitingAsync
功能后不能等待消息?
答:
因为console.log('done...')
不是异步的。
(它不返回Promise。)
问题 3:
主要问题:waitingAsync
是一个异步函数,为什么
await
调用它时不需要关键字?
答:
嗯,在你的例子waitingAsync
中没有返回任何值。- 如果它会返回一个您关心的值,那么您需要等待它来获取它。
(Hello world!
在我下面的堆栈片段中。)
问题 4:
如果我可以 await waitingAsync()
,[the]done...
消息将在最后打印 [?]
回答:
这取决于你的意思。– 请参阅下面的堆栈片段!只要Done!
消息在与 call 相同的回调中打印
await waitingAsync()
,答案就是Yes!
但是,如果您console.log('done...?')
在调用包含的异步函数之后放置,await waitingAsync()
那么答案是否定的!
运行下面的代码片段时,请注意输出的顺序!另请
注意显示需要 1400毫秒Promise resolved!
。
function waiting () {
return new Promise(resolve => {
console.log('awaiting...');
setTimeout(function () {
resolve('Hello world!');
console.log('Promise resolved!');
}, 1400);
});
}
async function waitingAsync () {
console.log('start...');
const toBeReturned = await waiting();
console.log('stop...');
return toBeReturned;
}
(async () => {
console.log('Heads up! The next line makes an asynchronous call.');
console.log('Result: ' + await waitingAsync()); // 'Hello world!'
console.log('Done! This will be printed LAST! - Agreed?');
})();
console.log('done...?? This is LAST in the CODE. - I awaited \
"waitingAsync()" above. - So will this be printed at the very end??');
.as-console-wrapper { max-height: 100% !important; top: 0; }
最后一个异步函数是匿名的——没有名字——并被立即调用。事实上,这是在代码片段中直接调用的唯一函数。该函数waitingAsync
仅被直接调用(通过匿名函数),并且该函数也被间接调用
(通过)。waiting
waitingAsync
带走的教训
永远不要在调用异步函数之后和之外放置顺序/同步代码!
如果你这样做,你只会让自己感到困惑。– 即使您没有感到困惑,您的代码的其他读者也几乎肯定会感到困惑。