为什么JS Promise的异步执行器和异步处理程序方法的行为会有所不同?

时间:2018-10-01 12:53:40

标签: javascript node.js promise async-await

在示例中使用Promise和async / await作为执行程序功能时,我观察到了一种我无法清楚理解的行为。 在执行以下任一情况时,将引发“ UnhandledPromiseRejectionWarning”警告:

案例1

new Promise(async function(resolve, reject) {
    var x = await new Promise(
        function(res, rej) {setTimeout(function() { rej("3b") }, 2000) 
    });
    resolve(x);
}).then(function(result) {
    console.log("3b. Result: " + result);
}).catch(function(err) {
    console.log("3b. Error: " + err);
});

案例2

new Promise(async function(resolve, reject) {
    var x = await new Promise(
        function(res, rej) { throw "3c" }
    );
    resolve(x);
}).then(function(result) {
    console.log("3c. Result: " + result);
}).catch(function(err) {
    console.log("3c. Error: " + err);
});

但是,如果我将异步函数的代码块包含在try-catch中,如下所示:

new Promise(async function(resolve, reject) {
    try {
        var x = await new Promise(
            function(res, rej) { throw "3c" }
        ); 
        resolve(x);
    }
    catch (err) {
        reject(err);
    }
}).then(function(result) {
    console.log("3c. Result: " + result);
}).catch(function(err) {
    console.log("3c. Error: " + err);
});

它输出“ 3c。Error:3c”(与情况1类似,在应用try-catch后输出变为“ 3b。Error:3b”)。

另一方面,如果我在处理程序中使用类似的异步函数并且没有try-catch,则不会导致任何“ UnhandledPromiseRejectionWarning”:

案例3

new Promise(async function(resolve, reject) {
    var x = await new Promise(
        function(res, rej) { setTimeout(function() { res("3d-1") }, 1000) }
    );
    return resolve(x);
}).then(async function(result) {
    console.log("3d-1. Result: " + result);
    var x = await new Promise(function(res, rej) { setTimeout(function() { rej("3d-2") }, 2000) });
    return x;
}).then(function(result) {
    console.log("3d-2. Result: " + result);
}).catch(function(err) {
    console.log("3d. Error: " + err);
});

案例4

new Promise(async function(resolve, reject) {
    var x = await new Promise(function(res, rej) { setTimeout(function() { res("3e-1") }, 1000) });
    return resolve(x);
}).then(async function(result) {
    console.log("3e-1. Result: " + result);
    var x = await new Promise(function(res, rej) { throw "3e-2" }); // Throwing error from timer can't be handled and hence program crashes.
    return x;
}).then(function(result) {
    console.log("3e-2. Result: " + result);
}).catch(function(err) {
    console.log("3e. Error: " + err);
});

在这里它输出:Case 3的3d-1. Result: 3d-13d. Error: 3d-2(与Case-4类似)。

我们可以看到Case-3和Case-4分别与Case-1和Case-2非常相似,不同之处在于拒绝(或抛出)现在发生在 then 块内。在这里,我没有将拒绝块放入try-catch中,但仍然可以工作。

请有人帮助我了解async-await和Promise的行为。
预先感谢。

0 个答案:

没有答案