Цепная множественная асинхронная функция с использованием обещаний - PullRequest
0 голосов
/ 22 октября 2019

В этом коде:

new Promise((resolve, reject) => {
    DB.get(params, function(err, data) {
        if (err) reject(err)
        else resolve(data.Item)
    })
})
.then((data) => {
    let params = { Name: 'DEMO' }
    CWevents.putRule(params, function(err, data) {
        if (err) console.log("Error", err)
        else console.log("Success")
    })
})
.then(() => {
    let params = { Rule: 'DEMO' }
    CWevents.putTargets(params, function(err, data) {
        if (err) console.log("Error", err)
        else console.log("Success", data)
    })
})

Функция DB.get здесь имеет обратный вызов, но было бы ужасно помещать несколько обратных вызовов друг в друга, поэтому я решил использовать обещания. Я создаю новое обещание, внутри которого есть асинхронная функция. После завершения работы он разрешается, и первый .then начинает работать по желанию. Затем внутри этого первого .then у меня есть еще одна асинхронная функция, которая работает так же, как и первая.

Но на этот раз не нужно запускать resolve/reject. Таким образом, третий .then запускается до завершения функции внутри второго .then. Как я могу заставить третий .then ждать, пока второй закончит работу? Итак, функция 1 завершает работу, затем функция 2, затем 3?

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Вы можете заключить вызов CWEvents.putRule в Обещание. Затем вы можете позвонить по решению или отклонить обещание от CWEvents.putRule. Это может быть зафиксировано then или error

Ваш код должен выглядеть следующим образом

new Promise((resolve, reject) => {
    DB.get(params, function(err, data) {
        if (err) reject(err);
        else resolve(data.Item);
    });
})
    .then(data => { // data not needed as you are not using it in the remaining code
        let params = { Name: "DEMO" };
        return new Promise((resolve, reject) => {
            CWevents.putRule(params, function(err, data) {
                if (err) {
                    console.log("Error", err);
                    reject(err)
                } else {
                    console.log("Success");
                    resolve() // resolve(data) if you want to pass the data from CWEvents.putRule
                }
            });
        });
    })
    .then(() => {
        let params = { Rule: "DEMO" };
        CWevents.putTargets(params, function(err, data) {
            if (err) console.log("Error", err);
            else console.log("Success", data);
        });
    });

Вы можете сделать то же самое в гораздо более удобочитаемом виде, используя async await

async function process() {
    try {
        var data = new Promise((resolve, reject) => {
            DB.get("params", function(err, data) {
                if (err) reject(err);
                else resolve(data.Item);
            });
        }); // this will return a promise to the variable data

        var response = (function processData(data) {
            let params = { Name: "DEMO" };
            return new Promise((resolve, reject) => {
                CWevents.putRule(params, function(err, data) {
                    if (err) {
                        console.log("Error", err);
                        reject(err);
                    } else {
                        console.log("Success " + data.Item);
                        resolve(data);
                    }
                });
            });
        })(await data);
        /* by using the await keyword , we can wait for the promise to be complete before moving on to the next step
          of execution.
        */

        /*
         * waiting on the response promise to complete
         */
        if (await response) {
            let params = { Rule: "DEMO" };
            CWevents.putTargets(params, function(err, data) {
                if (err) console.log("Error", err);
                else console.log("Success", data);
            });
        }
    } catch (e) {
        console.log("Error occured during operation " + e);
    }
}

process();

Более подробную информацию о async await вы можете найти в MDN

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

Я нашел решение. Внутри .then вы можете создать новое Обещание и вернуть его следующему .then, как это

new Promise((resolve, reject) => {
    setTimeout(() => {resolve(1)}, 1000)
})
.then((message) => {
    console.log(message)
    return new Promise((resolve, reject) => {
        setTimeout(() => {resolve(2)}, 5000)
    })
})
.then((message) => {
    console.log(message)
    return new Promise((resolve, reject) => {
        setTimeout(() => {resolve(3)}, 1000)
    })
})

. Это будет синхронно объединять их в цепочку, поэтому на выходе получится 1, 2, затем 3Без конструкции он вывел бы 1 и 3 одновременно, а затем 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...