Javascript 节点正在等待异步函数完成foreach
大家好,我一直在尝试使用异步模块来实现这一点,但我不知道如何将其转换为一个。我承诺它没有真正正常工作。我认为我做得不对,所以我将函数还原为最初的方式 基本上,我想等到ReadJson()函数读取完数组中的所有json文件后,再执行其他函数,如editjson等 代码: App.jsJavascript 节点正在等待异步函数完成foreach,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,大家好,我一直在尝试使用异步模块来实现这一点,但我不知道如何将其转换为一个。我承诺它没有真正正常工作。我认为我做得不对,所以我将函数还原为最初的方式 基本上,我想等到ReadJson()函数读取完数组中的所有json文件后,再执行其他函数,如editjson等 代码: App.js const Reader = require('./Reader'); Reader.ReadJson(); Reader.js const fsp = require('fs-promise'); const J
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!
谢谢:)返回承诺,在
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;
const fsp=require('fs-promise');
constjsonfiles=['json1.json','json2.json','json3.json','json4.json'];
const JsonContents=[];
类读取器{
静态ReadJson(){
var承诺=[];
for(设i=0;i{
如果(内容){
JsonContents.push(内容);
log(`Loaded>${JsonFiles[i]}${Reader.JsonContents.length}/${JsonFiles.length}`);
}
}));
}
返回承诺。全部(承诺);
}
}
Reader.JsonContents=JsonContents;
module.exports=读卡器;
返回承诺,在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;
const fsp=require('fs-promise');
constjsonfiles=['json1.json','json2.json','json3.json','json4.json'];
const JsonContents=[];
类读取器{
静态ReadJson(){
var承诺=[];
for(设i=0;i{
如果(内容){
JsonContents.push(内容);
log(`Loaded>${JsonFiles[i]}${Reader.JsonContents.length}/${JsonFiles.length}`);
}
}));
}
返回承诺。全部(承诺);
}
}
Reader.JsonContents=JsonContents;
module.exports=读卡器;
作为Promise.all方法的附录
promise库提供了一些帮助函数,如和,可以删除promise数组处理代码的大量模板
const Promise = require('bluebird');
const fsp = require('fs-promise');
const path = require('path');
class Reader {
static readFiles(jsonPath, jsonFiles){
let fileReadCount = 0;
return Promise.map(jsonFiles, name => {
let filePath = path.join(jsonPath, name);
return fsp.readJson(filePath);
})
.filter((content, index, length) => {
if (!content) return false;
console.log(`Loaded >> ${jsonFiles[index]} ${index+1} / ${length}`);
return true;
})
}
static readJson() {
return this.readFiles(this.jsonPath, this.jsonFiles).then(contents => {
console.log('Done Reading Json Content!', contents);
return this.jsonContents = contents;
})
}
}
Reader.jsonFiles = ['json1.json', 'json2.json', 'json3.json', 'json4.json'];
Reader.jsonPath = 'D:\\Development\\Java';
module.exports = Reader;
作为承诺的附录。所有方法
promise库提供了一些帮助函数,如和,可以删除promise数组处理代码的大量模板
const Promise = require('bluebird');
const fsp = require('fs-promise');
const path = require('path');
class Reader {
static readFiles(jsonPath, jsonFiles){
let fileReadCount = 0;
return Promise.map(jsonFiles, name => {
let filePath = path.join(jsonPath, name);
return fsp.readJson(filePath);
})
.filter((content, index, length) => {
if (!content) return false;
console.log(`Loaded >> ${jsonFiles[index]} ${index+1} / ${length}`);
return true;
})
}
static readJson() {
return this.readFiles(this.jsonPath, this.jsonFiles).then(contents => {
console.log('Done Reading Json Content!', contents);
return this.jsonContents = contents;
})
}
}
Reader.jsonFiles = ['json1.json', 'json2.json', 'json3.json', 'json4.json'];
Reader.jsonPath = 'D:\\Development\\Java';
module.exports = Reader;
?stackoverflow上已经有几十个问题和几十个答案,关于如何像您一样对异步操作循环排序。我建议您找到这些并从中学习。一个解决方案:?stackoverflow上已经有几十个问题和几十个答案,关于如何像您一样对异步操作循环排序。我建议您找到它们并从中学习。一种解决方案:这是一种反模式,用于在
fsp.readJson()
已经做出承诺时创建包装承诺。如果需要顺序操作,您可以链接这些承诺。@jfriend00这就是Promise的目的。所有的示例,还有一个递归承诺选项,我没有提到过,所以它不会是“过于复杂”的解决方案。您明白该解决方案是什么吗?通过更智能地使用promise返回的形式fsp.readJson()
,您可以对第一个代码块进行排序,但仍然不会封装在新创建的promise中。这样做还有其他好处,比如它会在出错时停止循环,而不是像您的解决方案那样继续完成整个循环的其余部分。我接受您的评论,但不知道如何在没有递归的情况下完成。如果可以的话,我很想看到并了解当fsp.readJson()
已经做出承诺时,这是一种如何创建包装承诺的反模式。如果需要顺序操作,您可以链接这些承诺。@jfriend00这就是Promise的目的。所有的示例,还有一个递归承诺选项,我没有提到过,所以它不会是“过于复杂”的解决方案。您明白该解决方案是什么吗?通过更智能地使用promise返回的形式fsp.readJson()
,您可以对第一个代码块进行排序,但仍然不会封装在新创建的promise中。这样做还有其他好处,比如它会在出错时停止循环,而不是像您的解决方案那样继续完成整个循环的其余部分。我接受您的评论,但不知道如何在没有递归的情况下完成。如果能做到的话,我很想看看并学习如何做到