NodeJS - Восстановление после попытки сброса брошенной ошибки, в середине цепи обещаний (асинхронный - «второй путь») - PullRequest
0 голосов
/ 22 октября 2018

Недавно я столкнулся с проблемой, которая возникла из-за асинхронной природы NodeJS.
У меня есть ситуация, когда я пытаюсь выдать request на один сервер, и если он не работает (из-заtimeout, например), я «заменяю» его - путем выдачи request другому серверу для предоставления мне данных и продолжения выполнения кода.
В настоящий момент происходит то, что однажды catchметод вызывается, я не уверен, как "вернуться" туда, где он остановился, и продолжить цепочку .then (Promise).
Конечно, я могу написать код после .catch и посмотреть еговыполняется, но, вероятно, произойдут 2 вещи:
1. Этот код будет выполняться асинхронно «без ожидания».
2. Мне придется повторять большие куски кода снова и снова, одновременно вкладывая их в каждуюдругие, используя обещания и блокирующиеся блоки, которые возвысят «Обещания-цепочки-ад», и которые, очевидно, или, вероятно, не являются правильным способом достижения.

Краткое описание того, чего я пытаюсь достичь:

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.');
        });

Должен ли я использовать внешнюю функцию для определения этих "маршрутов восстановления"?
Спасибо.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Вы просто возвращаете обещание в область действия then(){}, а обещания позаботятся об остальном.Таким образом, как вы сами сказали, вы можете прикрепить блок «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 выполнитьвыполнять.

0 голосов
/ 22 октября 2018

Вы должны создать общую функцию для того, что происходит, когда 1-й / 2-й запрос выполняется успешно.Эта функция может быть вызвана в обоих случаях без дублирования кода.

request(options1)
    .then(function (response) {
        //Server 1 is working - execute what's inside .then
        return request3(response);
    })
    .catch(function (err) {
        //Timeout has been thrown, show an error and continue
        return request(options2)
        .then(function (response) {
            return request3(response);
        });
    });

function request3() {
    // return a promise here
}
...