Node.js 等待循环中读取的所有文件
Posted
技术标签:
【中文标题】Node.js 等待循环中读取的所有文件【英文标题】:Node.js wait for all files read in the loop 【发布时间】:2018-08-02 01:03:50 【问题描述】:我是 javascript/node.js 事件驱动范例的新手。
我需要在 forEach 之后停止 for 以确保所有文件都已被读取,然后我继续。在这种情况下我应该如何实现wait_for_all_files_read()
?
my_list.forEach(function(element)
fs.readFile(element.file_path, function(err, data)
if(err) throw err;
element.obj=JSON.parse(data);
);
);
wait_for_all_files_read(); <-----------
analyze(my_list)
[1] 或 [2] 都不适合我。
【问题讨论】:
【参考方案1】:我会怎么做:
-
Promisify fs.readFile(通过使用,例如 Bluebird)
将函数标记为异步
制作回调列表(my_list.map 而不是 forEach)
“等待 Promise.all(myListOfCallbacks)”
等待后的下一行将在所有操作完成后执行
类似的东西:
const promisisfy = require('util')
const fs = require('fs')
const readFile = promisify(fs.readFile)
const fileNames = getFilenamesArray();
async function executeMe()
try
const arrayWithFilesContent = await Promise.all(
fileNames.map(name => readFile(name))
);
return analyze(arrayWithFilesContent);
catch (err)
handleError(err)
executeMe();
【讨论】:
但readFIle
内部有一个回调。如何考虑?
当它被承诺时,它会返回承诺。我们可以使用 promise .then(或 await)而不是提供回调作为参数。
那么,我应该把if(err) throw err;
和element.obj=JSON.parse(data);
放在哪里?
你可以删除 try/catch 块,而不是 Promise.all 会抛出错误。关于元素 - 你可以在 Promise.all 之后的循环中完成
我很困惑。【参考方案2】:
我可以建议您重写代码以实现承诺 - 这样处理起来会容易得多
const promisisfy = require('util')
const fs = require('fs')
const readFile = promisify(fs.readFile)
const fileNames = getFilenamesSomehow() // <-- returns array with path, e.g. ["./package.json", "/etc/hosts", "/etc/passwd"]
Promise.all(fileNames.map(name => readFile(name)))
.then(arrayWithFilesContent => analyze(arrayWithFilesContent))
.catch(err => handleError(err))
下一步你可以做什么 - 将代码移动到 async/await 函数中
UPD
假设您只需要读取一个文件,然后将其数据解析为 json 并以某种方式分析结果。
这种情况下你可以做下一步:
readFile(singleFileName)
.then(function (singleFileContent)
return JSON.parse(singleFileContent)
)
.then(function (singleFileContentInJson)
return analyze(singleFileContentInJson)
)
.catch(funciton (error)
//here you can process all errors from functions above: reading file error, JSON.parse error, analyze error...
console.log(error)
)
然后假设您需要分析一堆文件
const fileNames = [...] // array with file names
// this create an array of promises, each of them read one file and returns the file content in JSON
const promises = fileNames.map(function (singleFileName)
return readFile(singleFileName)
.then(function (singleFileContent)
return JSON.parse(singleFileContent)
)
)
// promise all resolves (calls callback in 'then') all of promises in array are resolved and pass to then callback array with result of each promise
Promise.all(promises)
.then(function (arrayWithResults)
return analyze(arrayWithResults)
)
// catch callback calls if one of promises in array rejects with error from the promise - so you can handle e.g. read file error or json parsing error here
.catch(function (error)
//here you can handle any error
console.log(error)
)
尝试在谷歌上搜索一些文章来阅读 Promise 是如何工作的。 例如。你可以开始表单mdn article
【讨论】:
我可以用function(name) ...
代替name => readFile(name)
吗?
在readFile
里面我有另一个回调,它是否也等待所有的内部回调?
不。 Promisify
function 只是将已作为参数传递的函数与 promise 包装起来。
但readFIle
内部有一个回调。如何考虑?
另外,我应该把if(err) throw err;
和element.obj=JSON.parse(data);
放在哪里?以上是关于Node.js 等待循环中读取的所有文件的主要内容,如果未能解决你的问题,请参考以下文章