javascript - 使用 Promise.reject() 创建的 Promise 会立即被调用
问题描述
执行此程序时
const somePromise = Promise.reject("Shouldn't see this");
function f1() {
console.log("Hello World");
}
f1();
产生以下输出
Hello World
(node:23636) UnhandledPromiseRejectionWarning: Shouldn't see this
(node:23636) 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(). (rejection id: 1)
(node:23636) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
为什么 Promise 会被执行?
这是否意味着使用 Promise.reject (或resolve
就此而言)创建的 Promise 将始终在调用块中创建后的某个时间点执行?
有没有办法为 Promise 创建一个默认值,以帮助对函数进行类型检查并避免Variable 'f2Promise' is used before being assigned.
警告,如下例所示:
function f2() {
let f2Promise: Promise<any>; // = Promise.reject("This is the default rejection");
const firstArg = undefined;
someFuncWithCallback(firstArg, (cbArg) => {
console.log("In callback");
f2Promise = someAsyncFunc(cbArg)
.then((val) => {
return val;
})
.catch((err) => {
return Promise.reject(`Error because of issue in someAsyncFunc with val: ${err}`);
});
});
return f2Promise;
}
我知道我可以通过断言f2Promise
不会为空来解决这个问题,但我希望有更多内在的方法来处理这个问题。
解决方案
承诺根本不会被“执行”。Promise 就像是一个操作结果的容器,它可以是:
- 待办的
- 被拒绝
- 解决
您创建了已被拒绝的承诺。
在您的代码中,您从一个 Promise 中捕获了一个错误,并立即抛出一个新错误。这不是必需的。以下是您可能想要重写该代码的方式:
function f2() {
const firstArg = undefined;
return new Promise((res) => {
someFuncWithCallback(firstArg, (cbArg) => {
res(someAsyncFunc(cbArg));
});
});
}
就个人而言,我更喜欢通常使用辅助函数来执行此操作:
const { promisify } from 'util';
const promisifedFunc = promisify(someFuncWithCallback);
function f2() {
const firstArg = undefined;
return promisifiedFunc(firstArg)
.then(cbArg => someAsyncFunc(cbArg);
}
一些核心思想是这两个是相同的:
return someAsyncOp().then( res => {
return res;
}
// Behaves the same as:
return someAsyncOp();
这三个也或多或少相同(这里有更多细微差别)。
return someAsyncOp()
.catch(err => {
return Promise.reject('Message');
});
// And
return someAsyncOp()
.catch(err => {
throw new Error('Message');
});
// And
return someAsyncOp();
这三个之间的区别是“抛出什么”。因此,如果您明确想要捕获一个错误只是为了抛出一个新错误,您可能需要中间选项。如果你不关心抛出了什么错误,你只想确保如果内部承诺失败,外部承诺也失败,只是不要抓住。
推荐阅读
- c# - 如何解决这个问题?“阅读器关闭时调用 CheckDataIsReady 的尝试无效”
- python - 如何获取 HTML 表单输入,通过 python 程序运行输入,以 HTML 输出响应
- python - 为什么我的python函数放在一个类中时运行方式不同
- mysql - 如何使用where子句解决左连接不起作用
- javascript - 如何将箭头函数转换为常规函数?
- r - CRAN 关于使用全局变量的政策
- android - Xamarin android:FirebaseInstanceIdService 已被弃用,但 FirebaseMessagingService 中没有 OnNewToken
- python - 将python登录到多个文件目的地的正确方法,从setting.ini文件而不组合级别
- angular - 在Angular的嵌套for循环中增加一个值计数器
- c# - 如何投影到具有其他一些实体的计数但没有导航属性的新类型