首页 > 解决方案 > NodeJS - 在 Promises-Chain 中从抛出错误的 try-catch 中恢复(异步 - “第二条路径”)

问题描述

最近我一直在努力解决一个由于 NodeJS 的异步特性而出现的问题。
我有一种情况,我尝试向request一台服务器发出 a ,如果它不起作用(timeout例如因为 a ),我“替换”它 - 通过向request另一台服务器发出 a 向我提供数据,并继续代码执行。
现在,实际发生的是,一旦catch调用该方法,我不确定如何“返回”到它停止的同一个地方,并继续.then(Promise)链。
当然,我可以在 .catch 之后编写代码并观察它的执行情况,但可能会发生两件事:
1. 此代码将“无需等待”异步运行。
2. 我必须一遍又一遍地复制大块代码,同时将它们相互嵌套,使用 promises 和 catch 块,这将提升“Promises-chaining-hell”,这显然是或可能是,不是正确的实现方式。

简要说明我要实现的目标:

const options1 = {
    method: 'GET',
    timeout: 1500,
    uri: 'https://www.example.com/'
}

const options2 = {
    method: 'GET',
    timeout: 1500,
    uri: 'https://www.example.com/'
}

const options3 = {
    method: 'GET',
    timeout: 1500,
    uri: 'https://www.example.com/'
}


    //Code before

    request(options1)
        .then(function (response) {
            //Server 1 is working - execute what's inside .then
            request(options3)
                .then(function (response) {
                    //Got the data from server 1 or 2, doesn't matter, now get the required data from server 3

                })
                .catch(function (err) {
                    //Timeout has been thrown, show an error and continue
                    console.log('Server 3 error occured, continuing.');
                });
        })
        .catch(function (err) {
            //Timeout has been thrown, show an error and continue
            request(options2)
            .then(function (response) {


            })
            .catch(function (err) {
                //Server 2 doesn't work either, abord and notify the user
                console.log('Server 2 error occured, continuing.');
            });
              console.log('Server 1 error occured, continuing.');
        });

我应该使用外部函数来定义那些“恢复路线”吗?
谢谢你。

标签: node.jsasynchronouspromiserequesttry-catch

解决方案


您只需将一个承诺返回给then(){}范围,其余部分由承诺处理。因此,正如您自己所说,您可以在 catch 之后附加一个“then”块,并编写它们的执行后代码,但是您需要向父级返回一个承诺,它负责链接和连续调用附加的回调。

像这样的东西:

//Code before

request(options1)
    .then(function (response) {
        console.log("Success 1")
        //Server 1 is working - execute what's inside .then
       return request(options3)
            .then(function (response) {
                //Got the data from server 1 or 2, doesn't matter, now get the required data from server 3
                console.log("Success 3")
            })
            .catch(function (err) {
                //Timeout has been thrown, show an error and continue
                console.log('Server 3 error occured, continuing.');
            });
    })
    .catch(function (err) {
        console.log("Failed 1")
        //Timeout has been thrown, show an error and continue
        return request(options2)
        .then(function (response) {

            console.log("Success 2")

        })
        .catch(function (err) {
            console.log("Failed 1")
            //Server 2 doesn't work either, abord and notify the user
            console.log('Server 2 error occured, continuing.');
        });
    })
    .then( ()=>{
        console.log("Post execution")

    } )

希望能帮助到你。

您可以通过在内部抛出错误以及超时来验证,然后强制执行 catch 块。


推荐阅读