Javascript-Async

Javascript-Async,javascript,node.js,d3.js,Javascript,Node.js,D3.js,我正在开发一个在d3中创建可视化的项目。 我有一个数组,其中包含要按顺序加载的文件名 但是,当运行数组并调用相应的方法时,数组中的第二个元素在第一个元素完成加载之前就被调用了 for(j=0;j<chosenAirports.length;j++) { var fileName = chosenAirports[j]; var splitData = fileName.split("_");

我正在开发一个在d3中创建可视化的项目。 我有一个数组,其中包含要按顺序加载的文件名

但是,当运行数组并调用相应的方法时,数组中的第二个元素在第一个元素完成加载之前就被调用了

        for(j=0;j<chosenAirports.length;j++)
        {
            var fileName = chosenAirports[j];
            var splitData = fileName.split("_");                
            readFile(splitData[0],selectedYear,splitData[0] + "_" +  selectedYear);
         }

for(j=0;j假设您正在读取一个文件,我猜这是在节点上运行的

如果是这样,则
readFile
函数要么调用节点的
readFile
函数,要么调用节点的
readFile
函数


正如您所说,这是一个异步函数。此函数的同步版本称为
readFileSync
,它可以防止您看到的问题。

如果您只是想让代码正常工作,使用synchronous
readFileSync()
方法将解决您的问题(详细信息如下:)


如果您对确保异步函数返回但仍然异步运行感兴趣,那么您可能会对使用RxJS承诺感兴趣。

如果您希望保持异步—我建议您这样做,因为不需要对抗节点/Javascript的核心—您可以将文件处理封装在承诺中:创建函数,该函数将文件名作为参数,并返回一个带有处理结果的承诺

比如:

function processFile(fileName) {
  return new Promise((resolve,reject) => {
    fs.readFile(fileName, function(err, data){
      if (err) {
        return reject(err);
      };
      return resolve(processData(data));
    });
  });
}
显然,您需要提供
processData()
函数,并确保它返回用于处理给定文件的数据

然后,要按顺序链接所有文件的处理,可以在数组上使用
reduce
方法,如:

const promise = chosenAirports.reduce((promise, fileName) => {
  return promise.then((previousResult) => {
    return processFile(fileName);
  })
}, Promise.resolve());
然后查询这个承诺的结果以获得最终结果

promise
.then((result) => {
  console.log('Result: ', result);
})
.catch((err) => {
  console.log(err);
});

处理数据和实现收集所有结果的机制由用户决定,但这种解决方案并不困难。

恐怕我把大家引向了错误的方向。readFile并不代表从文件中读取。它只是执行某些特定任务的函数的名称(与文件无关)。很抱歉没有提供完整的信息。由于您使用了名称
readFile()
,使我们所有人的头脑都乱了套,我们可以看看您的
readFile()
实际做了什么吗?如果函数是一个没有输入、输出或内部操作细节的黑盒,我们无法做出任何假设或提供帮助。