首页 > 解决方案 > 使用 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不会为空来解决这个问题,但我希望有更多内在的方法来处理这个问题。

标签: javascriptnode.jstypescriptpromise

解决方案


承诺根本不会被“执行”。Promise 就像是一个操作结果的容器,它可以是:

  1. 待办的
  2. 被拒绝
  3. 解决

您创建了已被拒绝的承诺。

在您的代码中,您从一个 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();

这三个之间的区别是“抛出什么”。因此,如果您明确想要捕获一个错误只是为了抛出一个新错误,您可能需要中间选项。如果你不关心抛出了什么错误,你只想确保如果内部承诺失败,外部承诺也失败,只是不要抓住。


推荐阅读