为什么我的异步函数在等待之后返回一个挂起的promise



我一定遗漏了什么,因为我不明白为什么我的承诺没有得到解决。

我把代码归结为一个简单的例子:

...
console.log("before");
const promise = second();
console.log("after");
console.log(promise);
...
async function first() {
const p1 = await axios.get("https://<url>");
console.log("first");
console.log(p1.data);
return (p1);
}
async function second() {
const p2 = await first();
console.log("second");
console.log(p2.data);
return (p2);
};

它在控制台中产生以下输出:

before
after
Promise { <pending> }
first
p1.data
second
p2.data

我的理解是wait会暂停执行,直到执行完成后再转到下一行,但这显然不会发生。

初始块以挂起的promise完成,然后执行异步函数中等待的代码,而不是暂停。

让我的代码暂停并等待,直到等待行完成已解决的承诺,然后再继续,我缺少什么?

在JavaScript中,以下所有情况都为真:

承诺

  • 是一个值(可以传递给函数、分配给变量等等(
  • 可以处于已解决被拒绝挂起状态
  • 它解析为的也是一个值(1"foo"{}…(
  • 可以将.then(...)回调链接到它
  • 可以awaited

async函数

  • 是一个同步返回promise的函数
  • 是一个异步返回该promise的解析值的函数

希望这个修改后的例子能让它更清楚:

// mock axios
const axios = {
get: url => Promise.resolve({ data: `Some data from ${url}` })
}
const fetchMockData = async () => {
const val = await axios.get('https://<url>')
return val
}
const withAsyncAwait = async () => {
console.log('=== with async/await ===')

const promise = fetchMockData() // not awaited
console.log('type of promise:', promise.constructor.name)
const resolved = await promise // here we await it
console.log('type of resolved:', resolved.constructor.name)
console.log('data:', resolved.data)
}
// equivalent but with `then` callback
const withThenCallback = () => {
console.log('=== with then callback ===')

const promise = fetchMockData() // not awaited
console.log('type of promise:', promise.constructor.name)
promise.then(resolved => { // resolved thanks to `then`
console.log('type of resolved:', resolved.constructor.name)
console.log('data:', resolved.data)
})
}
setTimeout(withAsyncAwait, 0)
setTimeout(withThenCallback, 100)

async function实际上并不像我们想象的那样是一个同步函数,它是一个承诺。所以你需要像承诺一样处理它,比如:

console.log("before");
second().then(res => {
console.log("after");
console.log(res);
});

异步函数就像Promise,不会立即解析。因此,您可能应该使用一个立即调用的匿名异步函数:

(async()=>{
console.log("before");
const promise = await second();
console.log("after");
console.log(promise);
})();

最新更新