如何使用Promise.all()和异步循环?

问题描述:

我试图围绕Promises和如何在异步循环中使用它们。如何使用Promise.all()和异步循环?

我收集了下面的代码读取的三个文件(使用forEach),当所有的承诺内容解析记录所有文件的输出:

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) 
}); 

我不知道如何把内环路.all()

我试过这段代码,但是这记录了一个空的数组。

我在做什么错?

+1

一)不使用'forEach'(但更好'map') b)你'*'推动诺言异步,当'Promise.all'接收它时,数组是空的。立即构建承诺,并且只异步解析* – Bergi

使用.map()来迭代您的数组,启动每个数组的异步调用,然后为每个调用返回承诺。该地图的返回值将是一组新的承诺,然后您可以将其传递给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); 
}); 

你混合回调与承诺,创建使用Array#map承诺的数组,并把它传递给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) 
}); 
+0

好!谢谢。另一个问题。如果文件名数组的源自身是异步函数的结果,该代码如何改变? – medicengonzo

+0

在这种情况下,您需要将加载文件名的函数添加到承诺链(从此函数开始承诺链):getFilesNames()。then(fileNames => Promise.all(fileNames.map(...)) ).then(values => ...)' – alexmac

+0

因此,我可以定义函数之前,然后只是调用它?另外,它应该返回一个承诺,对吗? – medicengonzo