kat*_*aik 3 javascript node.js promise async-await typescript
我有一个关于 Promise 在 Node.js 中如何工作的基本问题(在浏览器中,行为符合预期),请考虑以下函数作为示例:
async function proc(): Promise<void> {
const resolve = new Promise((resolve) => setTimeout(resolve, 0))
const reject = Promise.reject('reject')
console.log(await resolve)
try {
await reject
} catch (err) {
console.error(err)
}
}
Run Code Online (Sandbox Code Playgroud)
由于拒绝更快地出列,因此它被抛出await resolve,并且由于它没有在那里处理,所以我们得到了未处理的拒绝。
尽管有很多解决方案可以解决这个问题,但我发现这种行为违反直觉。是否有任何原因导致传递给的对象reject()在相应的 Promise 被执行时没有被抛出await,类似于传递给的对象resolve()在 时如何返回await?
我期望await做这样的工作:
await(promise) {
let result, error;
promise
.then((data) => result = data)
.catch((err) => error = err)
// wait for promise magic
if (error != null) {
throw error
}
return result
}
Run Code Online (Sandbox Code Playgroud)
这更多地与 NodeJS 如何响应“未处理的承诺拒绝”有关,其中默认值最近throw在Node 15中更改为。
每当发生未处理的 [promise] 拒绝时,都会采取以下步骤(文档):
unhandledRejection。因此,如果您有以下脚本:
// example.js
async function proc() {
const resolve = new Promise((resolve) => setTimeout(resolve, 0));
const reject = Promise.reject("reject");
await resolve;
console.log("Able to `await resolve`");
try {
await reject;
} catch (err) {
console.error('Caught an error!');
console.error(err);
}
}
proc();
Run Code Online (Sandbox Code Playgroud)
执行该脚本的结果会根据mode标志--unhandled-rejections的设置而变化。
如果将其设置为throw(默认值),您会看到程序永远不会继续越过该await resolve行,因为被拒绝的承诺在履行承诺之前抛出。
另请注意,如果您事先设置了process.on('unhandledRejection', ...),您也不会看到被拒绝的承诺抛出。
以下是您运行example.js脚本时可能会看到的内容:
$ node --unhandled-rejections=throw example.js
node:internal/process/promises:279
triggerUncaughtException(err, true /* fromPromise */);
^
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "reject".] {
code: 'ERR_UNHANDLED_REJECTION'
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您在模式设置为 的情况下运行它warn,您将看到如下内容:
$ node --unhandled-rejections=warn example.js
(node:55979) UnhandledPromiseRejectionWarning: reject
(Use `node --trace-warnings ...` to show where the warning was created)
(node:55979) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
Able to `await resolve`
Caught an error!
reject
(node:55979) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
Run Code Online (Sandbox Code Playgroud)
也就是说,我们能够到达该try块,因为被拒绝的 Promise 不会抛出未捕获的异常。
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |