我一定遗漏了什么,因为我不明白为什么我的承诺没有得到解决。
我把代码归结为一个简单的例子:
...
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(...)
回调链接到它 - 可以
await
ed
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);
})();