setInterval和promises产生一个PromiseRejectionHandledWarning

时间:2018-04-06 23:03:22

标签: javascript node.js es6-promise

我有一个应用程序,我不得不在后台运行一些异步代码。我创建了一个应用程序的最小模拟。

let promise_chain = Promise.resolve();
let rejected_promise_count = 0;

const interval_id = setInterval(
    // Do some important polling. I will just always reject to demonstrate the problem.
    () => {
        promise_chain = promise_chain.then(() => {
            rejected_promise_count += 1;
            return Promise.reject();
        })
    },
    10
);

// Set timeout simulates the program being done.
setTimeout(
    () => {
        clearInterval(interval_id);
        promise_chain
            .then(() => end("Resolved! :D"))
            .catch(() => end("Rejected! D:"));
    },
    1000
);

function end(message) {
    console.log(message);
    console.log(`Amount of rejected promises created: `, rejected_promise_count);
}

这给出了一长串列表:

(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) 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: 2)
(node:29217) [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.
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 2)
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) 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: 3)
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 3)
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) 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: 4)
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 4)

最终以这些结束:

(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) 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: 87)
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 87)
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) 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: 88)
Rejected! D:
Amount of rejected promises created:  1
(node:30920) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 89)

我不太清楚为什么节点不希望我异步处理这些节点,但鉴于它在一段时间内运行,我真的别无选择。

如何摆脱无休止的警告列表,更重要的是,如何确保未来节点不会终止此过程,因为它认为我没有处理拒绝?

1 个答案:

答案 0 :(得分:1)

这取决于你想做什么,处理它的正确方法是这样的:

const interval_id = setInterval(
    () => {
        promise_chain = promise_chain.then(() => {
            rejected_promise_count += 1;
            return Promise.reject();
        });
        //ignore error here, you catch it in the setTimeout
        promise_chain.catch(ignore=>ignore);
    },
    10
);

那将输出:

Rejected! D:
Amount of rejected promises created:  1

这是因为您第一次拒绝,因此链断了,所有其他then都没有执行。

如果你想继续执行并想知道有多少人通过并且失败了你可以做这样的事情:



//using actual results
let results = [];
//special Fail value to indicate rejected promise
let Fail = function(reason){this.reason=reason;};
let isFail = object=>(object&&object.constructor===Fail);
let isNotFail = object=>!isFail(object);

let promise_chain;
let somePromise = ()=>Promise.reject(new Error("Some reason"));

const interval_id = setInterval(
    () => {
        promise_chain = (promise_chain||somePromise())
        .then(
          result => {
            results.push(result);
            return somePromise();
          }
        )
        .catch(//catch the rejection and return a Fail type value
          error=>new Fail(error)
        );
},
    10
);

// Set timeout simulates the program being done.
setTimeout(
    () => {
        clearInterval(interval_id);
        promise_chain
        .then(
          result => {
            //add the last result to results
            results.push(result);
            console.log(
              "rejected promises:",
              results.filter(isFail).length
              //you can get the errors like so:
              //results.filter(isFail).map(fail=>fail.reason)
            );
            console.log(
              "resolved promises:",
              results.filter(isNotFail).length
              //results.filter(isNotFail) is an array of resolved values
            )
          }
        );
            //this will never reject because we catch rejected promises
            //  and add fail types to results
            // .catch(() => end("Rejected! D:"));
    },
    1000
);