javascript - Node JS Promise.all and forEach -
i have array structure exposes async methods. async method calls return array structures in turn expose more async methods. creating json object store values obtained structure , need careful keeping track of references in callbacks.
i have coded brute force solution, learn more idiomatic or clean solution.
- the pattern should repeatable n levels of nesting.
- i need use promise.all or similar technique determine when resolve enclosing routine.
- not every element involve making async call. in nested promise.all can't make assignments json array elements based on index. nevertheless, need use promise.all in nested foreach ensure property assignments have been made prior resolving enclosing routine.
- i using bluebird promise lib not requirement
here partial code -
var jsonitems = []; items.foreach(function(item){ var jsonitem = {}; jsonitem.name = item.name; item.getthings().then(function(things){ // or promise.all(allitemgetthingcalls, function(things){ things.foreach(function(thing, index){ jsonitems[index].thingname = thing.name; if(thing.type === 'file'){ thing.getfile().then(function(file){ //or promise.all? jsonitems[index].filesize = file.getsize();
it's pretty straightforward simple rules:
- whenever create promise in
then
, return it - promise don't return not waited outside. - whenever create multiple promises,
.all
them - way waits promises , no error of them silenced. - whenever nest
then
s, can typically return in middle -then
chains @ 1 level deep. - whenever perform io, should promise - either should in promise or should use promise signal completion.
and tips:
- mapping better done
.map
for/push
- if you're mapping values function,map
lets concisely express notion of applying actions 1 one , aggregating results. - concurrency better sequential execution if it's free - it's better execute things concurrently , wait them
promise.all
execute things 1 after other - each waiting before next.
ok, let's started:
var items = [1, 2, 3, 4, 5]; var fn = function asyncmultiplyby2(v){ // sample async action return new promise(resolve => settimeout(() => resolve(v * 2), 100)); }; // map on foreach since returns var actions = items.map(fn); // run function on items // have promises array , want wait var results = promise.all(actions); // pass array of promises results.then(data => // or .then(console.log) console.log(data) // [2, 4, 6, 8, 10] ); // can nest of course, said, `then` chains: var res2 = promise.all([1, 2, 3, 4, 5].map(fn)).then( data => promise.all(data.map(fn)) ).then(function(data){ // next `then` executed after promise has returned previous // `then` fulfilled, in case it's aggregate promise because of // `.all` return promise.all(data.map(fn)); }).then(function(data){ // measure return promise.all(data.map(fn)); }); // results: res2.then(function(data){ console.log(data); // [16, 32, 48, 64, 80] });
Comments
Post a Comment