NodeJS等待异步函数完成foreach

时间:2017-02-13 06:58:24

标签: javascript node.js asynchronous

嗨所以我一直试图让这个尝试使用异步模块并没有真正知道如何将其转换为一个尝试过的有希望它没有真正运作良好我认为我做错了所以我恢复了起作用的方式

基本上我想等到ReadJson()函数完成后读取数组中的所有json文件然后执行其他函数,如editjson等

代码:

App.js

const Reader = require('./Reader');
Reader.ReadJson();

Reader.js

const fsp = require('fs-promise');
const JsonFiles = ['json1.json', 'json2.json', 'json3.json', 'json4.json'];
const JsonContents = [];
class Reader {
    static ReadJson() {
        JsonFiles.forEach(name => {
            let FileDir = "D:\\Development\\Java\\" + name;
            fsp.readJson(FileDir).then(contents => {
                if (contents) {
                    JsonContents.push(contents);
                    console.log(`Loaded >> ${name} ${Reader.JsonContents.length}/${JsonFiles.length}`);
                }
            });
        });
        console.log('Done Reading Json Content!');
        //Other functions
    }
}
Reader.JsonContents = JsonContents;
module.exports = Reader;

所以基本上输出是:

Done Reading Json Content!
Loaded >> json1.json 1/4
Loaded >> json2.json 2/4
Loaded >> json3.json 3/4
Loaded >> json4.json 4/4

当我需要时:

Loaded >> json1.json 1/4
Loaded >> json2.json 2/4
Loaded >> json3.json 3/4
Loaded >> json4.json 4/4
Done Reading Json Content!

谢谢:)

2 个答案:

答案 0 :(得分:4)

返回承诺,跟踪forEach中的进度,并仅在JsonContents长度与JsonFiles长度相同时解决。

const fsp = require('fs-promise');
const JsonFiles = ['json1.json', 'json2.json', 'json3.json', 'json4.json'];
const JsonContents = [];
class Reader {
    static ReadJson() {
        return new Promise((resolve, reject) => {
            JsonFiles.forEach(name => {
                let FileDir = "D:\\Development\\Java\\" + name;
                fsp.readJson(FileDir).then(contents => {
                    if (contents) {
                        JsonContents.push(contents);
                        console.log(`Loaded >> ${name} ${Reader.JsonContents.length}/${JsonFiles.length}`);
                    }
                    if (JsonContents.length == JsonFile.length) {
                        return resolve(JsonContents);
                    }
                }).catch(err => {
                    return reject(err);
                });
            });
        });
    }
}
Reader.JsonContents = JsonContents;
module.exports = Reader;

然后在您的应用中使用它:

const Reader = require('./Reader');
Reader.ReadJson().then(() => { console.log('Done Reading Json Content!'); });

另一种选择是使用Promise.all,因为您使用的是fs-promise,但是虽然可以使用forEach完成,但常规的for循环在这里更好。

const fsp = require('fs-promise');
const JsonFiles = ['json1.json', 'json2.json', 'json3.json', 'json4.json'];
const JsonContents = [];
class Reader {
    static ReadJson() {
        var promises = [];
        for (let i = 0; i < JsonFiles.length; i++) {
            let FileDir = "D:\\Development\\Java\\" + JsonFiles[i];
            promises.push(fsp.readJson(FileDir).then(contents => {
                if (contents) {
                    JsonContents.push(contents);
                    console.log(`Loaded >> ${JsonFiles[i]} ${Reader.JsonContents.length}/${JsonFiles.length}`);
                }
            }));

        }
        return Promise.all(promises);
    }
}
Reader.JsonContents = JsonContents;
module.exports = Reader;

答案 1 :(得分:1)

作为Ron Dadon's Promise.all方法的附录......

Bluebird promise库提供了一些辅助函数,如Promise.mapPromise.filter,它们可以删除许多Promise数组处理代码的样板。

[meta]
  # Where the metadata/raft database is stored
  #dir = "/var/lib/influxdb/meta"
  dir = "C:\Users\User01\.influxdb\meta"