JS中async函数是否需含await?为何无Promise时await不生效?
关于JavaScript async/await工作机制的疑问与解释
我对JavaScript中的async/await工作机制存在困惑,已知await会使执行流程等待被调用函数完成。但在如下示例中,我无法理解为何myAsyncFunction内部必须包含Promise,才能让callerFunction中的await等待其执行完毕;同时也不解为何第二个未使用Promise的示例无法让执行流程等待:
第一个示例代码
async function myAsyncFunction() { console.log("Inside async function"); await new Promise(function(myResolve, myReject) { // "Producing Code" (May take some time) setTimeout(() => { console.log('setTimeout'); myResolve(); }, 3000); }); console.log("Async function resumed"); } async function callerFunction() { console.log("Before calling async function"); await myAsyncFunction(); console.log("After calling async function"); } callerFunction();
第二个示例代码
async function myAsyncFunction() { console.log("Inside async function"); setTimeout(() => { console.log('setTimeout'); }, 3000); console.log("Async function resumed"); } async function callerFunction() { console.log("Before calling async function"); await myAsyncFunction(); console.log("After calling async function"); } callerFunction();
核心逻辑:async/await 是 Promise 的语法糖
async函数本身会自动返回一个Promise,但await真正等待的是Promise的状态变更——只有当被等待的Promise从pending(等待)变为resolved(完成)或rejected(失败)时,await才会放行后续代码。
第一个示例能等待的原因
在第一个示例的myAsyncFunction中,我们用await new Promise(...)包裹了异步逻辑:
- 这个Promise内部的
setTimeout会在3秒后调用myResolve(),把Promise的状态从pending改成resolved - 只有等这个Promise状态变更后,
myAsyncFunction里await后面的console.log("Async function resumed")才会执行 - 同时,
myAsyncFunction返回的Promise会在内部所有await处理完成后才变为resolved,所以callerFunction里的await myAsyncFunction()会一直等到整个myAsyncFunction的异步逻辑走完,才会执行后续代码
它的执行顺序是:
- 打印
Before calling async function - 打印
Inside async function - 等待3秒后,打印
setTimeout - 打印
Async function resumed - 打印
After calling async function
第二个示例不能等待的原因
第二个示例的myAsyncFunction里没有await任何Promise:
setTimeout是浏览器的异步API,它会被放到任务队列里,当前同步代码会继续执行- 所以
myAsyncFunction会按同步顺序走完:先打印Inside async function,触发setTimeout(但不等待),直接打印Async function resumed - 此时
myAsyncFunction作为async函数,已经完成了所有同步逻辑,自动返回的Promise立刻变为resolved - 因此
callerFunction里的await myAsyncFunction()会直接放行,马上打印After calling async function - 3秒后任务队列里的
setTimeout回调才执行,打印setTimeout
它的执行顺序是:
- 打印
Before calling async function - 打印
Inside async function - 打印
Async function resumed - 打印
After calling async function - 等待3秒后,打印
setTimeout
总结
await不会等待普通异步API(比如直接调用setTimeout),它只识别Promise- 如果async函数内部没有
await任何未完成的Promise,会同步执行完所有代码,立刻返回resolved状态的Promise - 要让
await真正等待异步任务完成,必须把异步逻辑包装成Promise,并在async函数里await这个Promise
内容的提问来源于stack exchange,提问作者Saif Os
相关产品推荐
相关产品推荐

