所有标有“async”的函数都会返回一个 Promise 对象,即使它没有显式返回。于是我做了如下实验:
async function getPromise() {
setTimeout(() => { return "value"; }, 2000);
}
async function implicitPromiseTest() {
const val = await getPromise();
console.log(val); // prints "undefined"
}
implicitPromiseTest();
在示例 1 中,“return”之后的值应该隐式包装在 Promise 中。然后这个 Promise 将从函数中返回。我希望它能在“implicitPromiseTest”函数中得到解决,并将返回值打印到控制台。
我猜这不起作用,因为“getPromise”中的隐式 Promise 从未真正解决。完成此任务的正确方法是:
async function getPromise() {
return new Promise((resolve, reject) =>
{ setTimeout(() => { resolve("value"); }, 2000);})
}
async function implicitPromiseTest() {
const val = await getPromise();
console.log(val); // prints "value"
}
但这提出了问题:
如何解析从异步函数隐式返回的 Promise,而不从该函数的块显式返回 Promise?这样的功能可以让我大大简化我的代码。
如果这不能做到,那么异步总是隐式返回 Promise 的意义何在?如果无法解决或拒绝,这些 Promise 有什么用?
在我的第二个函数中,“await”关键字应该停止函数执行,直到“getPromise()”的 Promise 得到解析。由于它永远不会解决,因此执行应该无限期地停止。那为什么会执行“console.log”呢?
我想这不起作用,因为“getPromise”中的隐式 Promise 从未真正解决。
不是这个原因。它实际上立即解决了。您的
async
函数开始运行,然后设置超时,然后隐式返回 undefined
。由于这是一个 async
函数,因此 undefined
被包含在一个 Promise 中。一段时间后,超时结束,但这对已经完成其承诺的异步函数没有影响。
async/await 的存在是为了简化处理已有 Promise 的代码。它不会采用非承诺代码并将其转换为承诺代码,除非您返回非承诺代码。如果您想从
setTimeout
或任何其他基于回调的函数创建 Promise,那么您必须使用 new Promise
构造函数。
异步总是隐式返回 Promises 的意义何在?
所以你不必做
return Promise.resolve(someValue)
,你可以做return someValue
在我的第二个函数中,“await”关键字应该停止函数执行,直到“getPromise()”的 Promise 得到解析。因为它永远无法解决[...]
这是一个错误的前提。一旦超时到期,您显式创建的 Promise 将解析,这反过来又会导致
getPromise
返回的 Promise 解析。现在它已经解决了,任何等待它的代码都可以继续