从asynchronous函数与nodejs返回列表

我有以下代码:

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_copy_list )。 但在这种情况下,我不知道。

我听说了async.parallel但真的不知道如何申请。

input.csv

FirstPart;二部

testing/ test2的;无论/例子

只需将您的代码包装在一个承诺中,只有完成后才能解决。 一些人build议callback,这几乎是一样的东西,但现在这种模式是不鼓励的。 你应该真的使用承诺。

 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节开始,bluebird,Q等等都是不必要的。 除非您使用早期版本的节点,否则请尽量避免使用它们。 IMO。

鼓励Promise的原因是因为Node会实现asynchronous/等待,这将允许你调用这个完全相同的函数,如:

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

正如在注释中指出的,你不想从函数返回列表..你应该做的是包含一个callback作为getMediaList的参数,并调用callback与你的结果。 我会使用async.each循环通过文件中的行。 你可以在这里阅读更多关于async.each: https : //github.com/caolan/async#each 。 这里是一个例子:

 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 Promise = require('bluebird'), fs = require("fs"), media_copy_list, line_list, media_copy_list = []; fs.readFile("input.csv", function(err, data) { line_list = data.toString('utf-8').trim().split('\n'); Promise.map(line_list, function(file_line) { var output_path, source_path, split_list; if (file_line.length) { split_list = file_line.split(';'); 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 = { source: source_path, destination: output_path }; } } return media_copy_list }).then(function(values){ console.log(values); }) 

});