最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I use Promise.all() and an async loop? - Stack Overflow

programmeradmin3浏览0评论

I'm trying to wrap my head around Promises and how to use them on async loops.

I gathered the following code to read the contents of three files (using forEach) and when all promises resolve log the output of all files:

var Promise = require('bluebird');
var fs = require('fs');
var path = require('path');

var files = ['1.json','2.json','3.json'];
var promises = []

files.forEach(function(file){
    fs.readFile(path.join('./',file), 'utf8', function(err,data){
        promises.push(new Promise(function(resolve, reject){
            resolve(data)
        })
                );
    })
});

Promise.all(promises).then(function(values){
    console.log(values)
});

I don't know how to put the loop inside the .all()

I tried this code but this logs an empty array.

What am I doing wrong?

I'm trying to wrap my head around Promises and how to use them on async loops.

I gathered the following code to read the contents of three files (using forEach) and when all promises resolve log the output of all files:

var Promise = require('bluebird');
var fs = require('fs');
var path = require('path');

var files = ['1.json','2.json','3.json'];
var promises = []

files.forEach(function(file){
    fs.readFile(path.join('./',file), 'utf8', function(err,data){
        promises.push(new Promise(function(resolve, reject){
            resolve(data)
        })
                );
    })
});

Promise.all(promises).then(function(values){
    console.log(values)
});

I don't know how to put the loop inside the .all()

I tried this code but this logs an empty array.

What am I doing wrong?

Share Improve this question asked Sep 24, 2017 at 22:13 medicengonzomedicengonzo 5192 gold badges10 silver badges23 bronze badges 2
  • 1 a) don't use forEach (but better map) b) you're pushing the promise asynchronously, the array is empty when Promise.all receives it. Construct the promise immediately, and only resolve it asynchronously – Bergi Commented Sep 24, 2017 at 22:16
  • this article has it, nicely described medium./@bluepnume/… – MartianMartian Commented May 20, 2018 at 8:40
Add a ment  | 

2 Answers 2

Reset to default 5

You're mixing callbacks with promises, create an array of promises using Array#map and pass it to Promise.all:

var files = ['1.json', '2.json', '3.json'];
var promises = files.map(file => {
  return new Promise((resolve, reject) => {
    fs.readFile(path.join('./',file), 'utf8', (err, data) => {
      if (err) {
        return reject(err);
      }
      resolve(data);
    });
  });
});

Promise.all(promises).then(function(values){
    console.log(values)
});

Use .map() to iterate over your array, starting an async call for each, then returning the promise for each call. The return value from that map will be a new array of promises which you can then pass to Promise.all().

let Promise = require('bluebird')
let fs = Promise.promisifyAll(require('fs'))

let promises = files.map((file) => {
  // readFile will return promises because of bluebird promisifyAll
  return fs.readFile(...)
})

Promise.all(promises).then((results) => {
  // results will be an array of all the files that were read
  console.log(results);
});
发布评论

评论列表(0)

  1. 暂无评论