处理承诺中的错误

时间:2017-12-19 03:32:55

标签: javascript promise

我试图弄清楚如何正确处理承诺链中的错误。承诺很少,其中一个抛出错误。如果出现错误,我想终止链中的功能。

我面临的问题是:

  1. 我们如何终止来自catch块的下一个调用?
  2. 如何保证执行顺序然后()。catch()。then()链?在这 我发现在执行then()函数后调用catch块。
  3. 代码示例:

    function run() {
        test().then(function(data) {
            console.log("w3", "Print data: " + data);
        });
    }
    
    function test() {
        return new Promise(function(fulfill, reject) {
            ask()
                .catch(err => console.log("w3", "Process error from ask: " + err))
                .then(reply())
                .catch(err => console.log("w3", "Process error from reply: " + err))
                .then(function(data) {
                    console.log("w3", "Finish test");
                    fulfill(data);
                    // TODO finish data
                })
        });
    }
    
    function ask() {
        return new Promise(function(fulfill, reject) {
            console.log("w3", "ask");   
            // fulfill("Hello");
            reject("Cancel Hello");
        });
    }
    
    function reply() {
        return new Promise(function(fulfill, reject) {
            console.log("w3", "reply");
            fulfill("World!");
            // reject("Cancel World");
        });
    }
    

2 个答案:

答案 0 :(得分:2)

这不是Promise链的工作方式。如果你明确地从.then()块中调用的每个函数返回一个Promise,Promise将只能正确链接。如果您没有从这些函数中返回Promise,则会立即调用下一个.then()块。

你可能想做这样的事情:

function run() {
    test()
        .then(function (data) {
            console.log("w3", "Print data: " + data);
        });
}

function test() {
    return ask()
        .then(function (result) {
            return reply();
        })
        .then(function (data) {
            console.log("w3", "Finish test");
            return Promise.resolve(data);
        })
        .catch(function (error) {
            console.log("Hey an error was thrown from somewhere");
            if(error instanceof UnexpectedAskError) {
                //handle specific error logic here. 
            }
        });
}

function ask() {
    console.log("w3", "ask");
    return Promise.reject(new UnexpectedAskError("Ask threw an error"));
}

function reply() {
    console.log("w3", "reply");
    return Promise.resolve("World!");
}

注意ask函数如何返回特定类型的错误?如果您需要根据哪个函数引发错误执行不同的错误处理,您可以执行类似的操作。

专门回答您提出的问题:

  1. 如果上一个函数抛出错误,上面链接promise的方法将阻止调用下一个.then()
  2. 上述链接方法将确保按指定的顺序调用.then()块。只要每个.then()都是一个函数,并且每个函数都返回一个Promise,无论是通过构造new Promise(function(resolve, reject))还是通过Promise.resolve还是Promise.reject,该链都将以正确的方式执行顺序。

答案 1 :(得分:1)

你只是抓住了链条的尽头。如果有任何错误。它将忽略其他then并直接捕获。

function test() {
    return new Promise(function(fulfill, reject) {
        ask()
            .then(reply())
            .then(function(data) {
                console.log("w3", "Finish test");
                return fulfill(data); // <= Make sure to return here
                // TODO finish data
            })
            .catch(err => console.log("w3", "Process error from reply: " + err))
    });
}

确保返回Promise,否则它将无法捕获您的错误。

fulfill(data);应为return fulfill(data);