简体   繁体   中英

Promise created with Promise.reject() gets called immediately

When executing this program

const somePromise = Promise.reject("Shouldn't see this");

function f1() {
    console.log("Hello World");
}
f1();

The following output is produced

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.

Why is the Promise getting executed?

Does this mean that a Promise created with Promise.reject (or resolve for that matter) will always get executed at some point after creation within a calling block?

And is there a way to create a default value for a Promise to assist in type checking of the function and to avoid Variable 'f2Promise' is used before being assigned. warnings, like the example below:

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;
}

I know that I could possible to work around this issue, by asserting the f2Promise will not be null, but I would hope for more intrinsic ways to handle this.

Promises don't get 'executed' at all. A promise is like a container for the result of an operation that's either:

  1. Pending
  2. Rejected
  3. Resolved

You created promise that's already rejected.

In your code you are catching an error from a promise, and immediately throw a new one. This isn't needed. Here's how you might want to rewrite that code:

function f2() {
  const firstArg = undefined;
  return new Promise((res) => {
    someFuncWithCallback(firstArg, (cbArg) => {
      res(someAsyncFunc(cbArg));
    });
  });
}

Personally I prefer usually doing this with a helper function:

const { promisify } from 'util';

const promisifedFunc = promisify(someFuncWithCallback);

function f2() {
  const firstArg = undefined;
  return promisifiedFunc(firstArg)
    .then(cbArg => someAsyncFunc(cbArg);
}

Some core ideas is that these two are the same:

return someAsyncOp().then( res => {
  return res;
}

// Behaves the same as:

return someAsyncOp();

And these 3 are also more or less the same (there's more nuance here).

return someAsyncOp()
  .catch(err => {
    return Promise.reject('Message');
  });

// And

return someAsyncOp()
  .catch(err => {
    throw new Error('Message');
  });

// And

return someAsyncOp();

The difference between these 3 is 'what is thrown'. So if you explicitly want to catch an error just to throw a new one, you probably want the middle option. If you don't care about what error is thrown and you just want to make sure that if the inner promise fails, the outer promise fails too just don't catch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM