为什么 promise reject 不处理错误
Why promise reject does not handle an error
我正在使用节点 v10.24.1
的 nodejs request
包(2.88 版本)
如果没有指定 url,下面的 Promise 不会处理错误。我得到 UnhandledPromiseRejectionWarning
并且从 request package
来源我可以看到针对该情况抛出的异常。
如果我删除 async
关键字,一切正常,并且拒绝处理。
return new Promise(async (resolve, reject) => {
request(uri: url).on('error', err => {
reject();
}).on('response', response => {
resolve();
});
});
你能解释一下发生了什么吗?可能请求的异常在实际触发拒绝之前完成。请提供任何详细信息。
当您将一个函数传递给 new Promise
时,此函数会立即 执行。
这里没有魔法,为了说明的目的,new Promise()
的构造函数可能看起来有点像这样:
class Promise {
constructor(executor) {
executor(this.resolveFunction, this.rejectFunction);
}
}
所以这个例子:
new Promise(() => {
console.log(1);
});
console.log(2);
输出:
1
2
这很重要,因为如果您将某些东西传递给 new Promise
并引发异常,这也会立即发生:
new Promise((res, rej) => {
throw new Error('foo');
});
这里抛出的错误不会导致 promise 被拒绝,它完全阻止了 new Promise()
成功。没有返回承诺,并且在调用 new Promise()
.
的 outer 函数中抛出异常
但是,当您传递一个异步函数时,这会崩溃:
new Promise(async (res, rej) => {
throw new Error('foo');
});
由于异步函数的工作方式,此错误将 不会 在 new Promise()
的设置期间抛出,但您传递的异步函数将异步处理错误并且returns 一个被拒绝的承诺,new Promise()
不知道如何处理。
这和自己直接调用异步函数,不处理错误没什么区别:
(async () => {
throw new Error('foo');
})();
所以事情失败的原因与 new Promise()
关系不大,但更多的是与异步函数的一般工作方式有关。
这是对未来读者的最后一次提醒,您永远不应将 async
执行程序传递给 new Promise()
,因为:
- 你需要
async
的唯一原因是你可以使用 await
.
await
仅适用于承诺。
- 如果你已经有一个你想要
await
的承诺,你不需要new Promise()
开始,因为主要用例new Promise
的目的是将 不 使用 promises 的东西转换成可以使用的东西。
我正在使用节点 v10.24.1
request
包(2.88 版本)
如果没有指定 url,下面的 Promise 不会处理错误。我得到 UnhandledPromiseRejectionWarning
并且从 request package
来源我可以看到针对该情况抛出的异常。
如果我删除 async
关键字,一切正常,并且拒绝处理。
return new Promise(async (resolve, reject) => {
request(uri: url).on('error', err => {
reject();
}).on('response', response => {
resolve();
});
});
你能解释一下发生了什么吗?可能请求的异常在实际触发拒绝之前完成。请提供任何详细信息。
当您将一个函数传递给 new Promise
时,此函数会立即 执行。
这里没有魔法,为了说明的目的,new Promise()
的构造函数可能看起来有点像这样:
class Promise {
constructor(executor) {
executor(this.resolveFunction, this.rejectFunction);
}
}
所以这个例子:
new Promise(() => {
console.log(1);
});
console.log(2);
输出:
1
2
这很重要,因为如果您将某些东西传递给 new Promise
并引发异常,这也会立即发生:
new Promise((res, rej) => {
throw new Error('foo');
});
这里抛出的错误不会导致 promise 被拒绝,它完全阻止了 new Promise()
成功。没有返回承诺,并且在调用 new Promise()
.
但是,当您传递一个异步函数时,这会崩溃:
new Promise(async (res, rej) => {
throw new Error('foo');
});
由于异步函数的工作方式,此错误将 不会 在 new Promise()
的设置期间抛出,但您传递的异步函数将异步处理错误并且returns 一个被拒绝的承诺,new Promise()
不知道如何处理。
这和自己直接调用异步函数,不处理错误没什么区别:
(async () => {
throw new Error('foo');
})();
所以事情失败的原因与 new Promise()
关系不大,但更多的是与异步函数的一般工作方式有关。
这是对未来读者的最后一次提醒,您永远不应将 async
执行程序传递给 new Promise()
,因为:
- 你需要
async
的唯一原因是你可以使用await
. await
仅适用于承诺。- 如果你已经有一个你想要
await
的承诺,你不需要new Promise()
开始,因为主要用例new Promise
的目的是将 不 使用 promises 的东西转换成可以使用的东西。