How to return the accumulated returned Promise values โ€‹โ€‹as an array in .then () after Array.prototype.reduce ()?

Given this pattern

someArray.reduce(function(p, item) {
  return p.then(function() {
    return someFunction(item);
  });
}, $.Deferred().resolve()).then(function() {
  // all done here
  // access accumulated fulfilled , rejected `Promise` values
}, function err() {

});

What approaches can return the accumulated values โ€‹โ€‹of worked-out, rejected Promiseobjects to .then(fulfilled)as an array following the call .reduce()?

function someFunction(index) {
  console.log("someFunction called, index = " + index);
  var $deferred = $.Deferred();

  window.setTimeout(function() {
    $deferred.resolve();
  }, 2000);

  return $deferred.promise();
}
   
var someArray = [1,2,3,4,5];

someArray.reduce(function(p, item) {
  return p.then(function() {
    return someFunction(item);
  });
}, $.Deferred().resolve()).then(function(data) {
  // all done here
  console.log(data, arguments) // `undefined` , `[]`
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
Run codeHide result
-5
source share
3 answers

There are several possible strategies depending on the specifics of what you are trying to do: here is one of the options:

someArray.reduce(function(p, item) {
  return p.then(function(array) {
    return someFunction(item).then(function(val) {
        array.push(val);
        return array;
    });
  });
}, $.Deferred().resolve([])).then(function(array) {
  // all done here
  // accumulated results in array
}, function(err) {
  // err is the error from the rejected promise that stopped the chain of execution
});

Working demo: http://jsfiddle.net/jfriend00/d4q1aaa0/


FYI, Bluebird ( ) .mapSeries(), :

var someArray = [1,2,3,4];

Promise.mapSeries(someArray, function(item) {
    return someFunction(item);
}).then(function(results) {
    log(results);
});

: http://jsfiddle.net/jfriend00/7fm3wv7j/

+8

:

var $j = function(val, space) {
  return JSON.stringify(val, null, space || '')
}
var log = function(val) {
  document.body.insertAdjacentHTML('beforeend', '<div><pre>' + val + '</div></pre>')
}

var async = function(cur){
  var pro = new Promise(function(resolve, reject) {

        log('loading : ' + cur.name);
        
        // we simualate the loading
        setTimeout(function() {
          if(cur.name === 'file_3.js'){
            reject(cur.name);
          }
          resolve(cur.name);
        }, 1 * 1000);

      });

      return pro;
}

var files = '12345'.split('').map(function(v) {
  return {
    name: 'file_' + v + '.js', 
  }
});


var listed = files.reduce(function(t,v){

  t.p = t.p.then( function(){
    return async( v )
      .then(function(rep){
      
               t.fulfilled.push(rep);
               log('fulfilled :' + rep); 
               return rep;
      
      } , function(rep){
               
               t.rejected.push(rep);
               log('-----| rejected :' + rep); 
               return rep;
      }
   ).then(function(val){ t.treated.push(val) })
  });
  
  return t;
  
} , {p : Promise.resolve() , treated : [] , fulfilled : [] , rejected : [] } )


listed.p.then( function(){ 
  log( 'listed : ' + $j( listed , '   ' )) 
});
Hide result
+2

, @jfriend00, , , promises, Promise.all .map.

promises, reduce . Promise.all , . , , , , - . , reduce, scan (, map) :

Array.prototype.scan = function scanArray(callback, accumulator) {
    "use strict";
    if (this == null) throw new TypeError('Array::scan called on null or undefined');
    if (typeof callback !== 'function') throw new TypeError(callback+' is not a function');

    var arr = Object(this),
        len = arr.length >>> 0,
        res = [];
    for (var k = 0; k < len; k++)
        if (k in arr)
            res[k] = accumulator = callback(accumulator, arr[k], k, arr);
    return res;
};

Promise.all(someArray.scan(function(p, item) {
    return p.then(function() {
       return someFunction(item);
    });
}, Promise.resolve())).then(โ€ฆ)

( jQuery Promise.resolve $.Deferred().resolve() Promise.all $.when.apply($, โ€ฆ))

+2

Source: https://habr.com/ru/post/1662183/


All Articles