Канонический способ позволить ряду обещаний («асинхронных функций, возвращающих обещания») выполняться последовательно - это их цепочка.
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
.Вы можете конвертировать код и посмотреть, какой подход вам больше нравится.