Последовательная облачная функция Firebase обещает - PullRequest
0 голосов
/ 09 декабря 2018

Я до сих пор не понимаю, как я мог заставить облачные функции работать последовательно.Вот мой код:

export const Run = functions.database.ref("PATH").onUpdate((snap, 
context) =>
{
const Collection = [];
ref.child('PATH2').once('value', function(lambda) 
{
    lambda.forEach((snap) => 
    {
        if (snap.val().state) 
        {
            Collection.push(snap.key);
        }
        return false; //since I use typescript I must return a boolean with foreach loop
    });
}).then(() => 
{
for (let i = 0; i < Collection.length; i++) 
{
    const arg = Collection[i];

        if(Verify(arg))
        {
            break;
        }

        Function_A(arg)
        .then(() => {
            return Function_B(arg)
        })
        .then(() => {
            return Function_C(arg);
        })
        .then(() => {
            return Function_D(arg);
        })
        .then(() => {
            return Function_E(arg)
        })
        .then(() => {
            return Function_F(arg)
        })
        .then(() => {
            return Function_G(arg)
        })
}
})
});

Проблема в том, что функция C запускается до завершения функции B.Как я могу сделать это работает последовательно?Мне действительно нужно, чтобы функция B была полностью выполнена перед переходом к следующей функции.

1 Ответ

0 голосов
/ 09 декабря 2018

Канонический способ позволить ряду обещаний («асинхронных функций, возвращающих обещания») выполняться последовательно - это их цепочка.

Promise.resolve(init)
    .then(result => function1(result))    // result will be init
    .then(result => function2(result))    // result will be the result of function1
    .then(result => function3(result));   // result will be the result of function2
                                          // overall result will be that of function 3

// more succinctly, if each function takes the previous result
Promise.resolve(init).then(function1).then(function2).then(function3);

Этот шаблон может быть выражен в общем виде, т. Е. С переменным числом функций, с использованием массива и вызова .reduce():

var funcs = [function1, function2, function3, functionN];
var chain = funcs.reduce((result, nextFunc) => nextFunc(result), Promise.resolve(init));

Здесь chain является единственнымобещание (последний в цепочке).Он разрешится, когда цепочка разрешится.

Теперь при условии, что у нас есть функции от A до G, и при условии, что lambda является массивом значений:

const funcSequence = [Function_A, Function_B, Function_C, Function_D, Function_E, Function_F, Function_G];

const chains = lambda
    .filter(snap => snap.val().state && Verify(snap.key))
    .map(snap => funcSequence.reduce((result, func) => func(snap.key), Promise.resolve(/* init */)));

chainsбудет массивом цепочек обещаний (точнее, массивом последних обещаний каждой цепочки ).Все цепочки будут работать параллельно, но каждая цепочка будет работать последовательно.Все, что нам нужно сделать сейчас, это дождаться их разрешения.

Promise.all(chains).then(results => console.log(results));

Todo: Добавить обработку ошибок.

Вышесказанное также можно сделать с помощью циклов и async /await.Вы можете конвертировать код и посмотреть, какой подход вам больше нравится.

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