Node.js 使用nodejs从异步函数返回列表

Node.js 使用nodejs从异步函数返回列表,node.js,Node.js,我有以下代码: var fs = require("fs"); function getMediaList(){ var media_copy_list, line_list; media_copy_list = []; fs.readFile("input.csv", function(err, data) { line_list = data.toString('utf-8').trim().split('\n'); return lin

我有以下代码:

var fs = require("fs");

function getMediaList(){
    var media_copy_list, line_list;
    media_copy_list = [];

    fs.readFile("input.csv", function(err, data) {

      line_list = data.toString('utf-8').trim().split('\n');
      return line_list.forEach(function(file_line) {
        var output_path, source_path, split_list;
        if (file_line.length) {
          split_list = file_line.split(';');
          console.log(split_list[0]);
          if (split_list.length >= 2) {
            source_path = split_list[0].toString('utf-8').trim();
            output_path = split_list[1].toString('utf-8').trim();
            media_copy_list.push({
              source: source_path,
              destination: output_path
            });
          }
        }
      });
    });
}
您可以看到,我正在用以下内容填充列表:

media_copy_list.push({
  source: source_path,
  destination: output_path
});
我想做的是在读完
input.csv
文件后返回此列表

如果我同步读取文件,我没有任何问题(只需调用
return media\u copy\u list
)。但在这种情况下,我不知道

我听说了
async.parallel
,但真的不知道如何应用

input.csv
示例:

第一部分;第二部分

测试/测试2;无论如何/举例


如注释中所述,您不希望从函数返回列表。。您应该做的是将回调作为参数包含到getMediaList中,并使用结果调用该回调。我将使用async.each循环文件中的行。您可以在此处阅读有关async的详细信息。每个:。以下是一个例子:

var fs = require("fs");

function getMediaList(callback){
    var media_copy_list, line_list;
    media_copy_list = [];

    fs.readFile("input.csv", function(err, data) {
      if(err) {
        return callback(err);
      }
      line_list = data.toString('utf-8').trim().split('\n');
      async.each(line_list, function(file_line, next) {
        var output_path, source_path, split_list;
        if (file_line.length) {
          split_list = file_line.split(';');
          console.log(split_list[0]);
          if (split_list.length >= 2) {
            source_path = split_list[0].toString('utf-8').trim();
            output_path = split_list[1].toString('utf-8').trim();
            media_copy_list.push({
              source: source_path,
              destination: output_path
            });
          }
        }
        next(err); 
      }, function (err) {
        callback(err, media_copy_list);
      }
    });
}
或者你可以使用承诺(下面的例子是蓝鸟)


}))

只需将代码包装在承诺中,并在完成后解决它。有些人建议回调,这几乎是同样的事情,但这种模式是不鼓励的,现在。你真的应该用承诺

var fs = require("fs");

function getMediaList(file){
  return new Promise(function (resolve, reject) {
    fs.readFile(file, 'utf-8', function(err, data) {
      if (err) {
        return reject(err);
      }

      resolve(data.split('\n').reduce(function(media_copy_list, file_line) {
        var output_path;
        var source_path;
        var split_list;

        file_line = file_line.trim();

        if (file_line.length) {
          split_list = file_line.split(';');
          console.log(split_list[0]);

          if (split_list.length >= 2) {
            source_path = split_list[0].toString('utf-8').trim();
            output_path = split_list[1].toString('utf-8').trim();
            media_copy_list.push({
              source: source_path,
              destination: output_path
            });
          }
        }

        return media_copy_list;
      }, []));
    });
  });
}
然后,调用

getMediaList('input.csv').then(function (mediaList) {
  // ...
}).catch(function (err) {
  console.error(err.stack);
});
注意:由于节点4.2+,蓝鸟、Q等都是不必要的。除非您使用的是早期版本的Node,否则请尽量避免使用它们。国际海事组织

之所以鼓励使用
Promise
s,是因为Node将实现async/await,这将允许您调用完全相同的函数,如:

var mediaList = await getMediaList('input.csv');

将结果返回到哪里?啊,对不起,实际上代码在函数中。因此函数应该返回它。请编辑问题并包含所有相关信息。可能的
var mediaList = await getMediaList('input.csv');