javascript - Resolve promises one after another (i.e. in sequence)? -


consider following code reads array of files in serial/sequential manner. readfiles returns promise, resolved once files have been read in sequence.

var q = require("q");  var readfile = function(file) {   ... // returns promise. };  var readfiles = function(files) {   var deferred = q.defer();    var readsequential = function(index) {     if (index >= files.length) {       deferred.resolve();     } else {       readfile(files[index]).then(function() {         readsequential(index + 1);       });     }   };    readsequential(0); // start!    return deferred.promise; }; 

the code above code works, don't having recursion things occur sequentially. there simpler way code can re-written don't have use weird readsequential function?

originally tried use q.all, caused of readfile calls happen concurrently, not want:

var readfiles = function(files) {   return q.all(files.map(function(file) {     return readfile(file);   })); }; 

update 2017: use async function if environment supports it:

async function readfiles(files) {   for(const file of files) {     await readfile(file);   } }; 

if you'd like, can defer reading files until need them using async generator (if environment supports it):

async function* readfiles(files) {   for(const file of files) {     yield await readfile(file);   } }; 

update: in second thought - might use loop instead:

var readfiles = function(files) {   var p = q(); // promise.resolve() without q    files.foreach(function(file){       p = p.then(function(){ return readfile(file); }); // or .bind   });   return p; }; 

or more compactly, reduce:

var readfiles = function(files) {   return files.reduce(function(p, file) {              return p.then(function(){ return readfile(file); });          },q()); // initial }; 

in other promise libraries (like when , bluebird) have utility methods this.

for example, bluebird be:

var promise = require("bluebird"); var fs = promise.promisifyall(require("fs"));  var readall = promise.resolve(files).map(fs.readfileasync,{concurrency: 1 }); // if order matters, can use promise.each instead , omit concurrency param  readall.then(function(allfilecontents){     // stuff read files. }); 

in q, have can - can shorten array.prototype.reduce bit , extract generic method.

if can use q.async (that you're on node) things better:

q.spawn(function* () {     var results = [];     for(var = 0;i < files.length; i++){         results.push(yield readfile(files[i]));     }     console.log(results); }); 

just remember run node --harmony and remember it's experimental atm.


Comments

Popular posts from this blog

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - SSE Emitter : Manage timeouts and complete() -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -