Javascript 在节点中异步读取文件
我试图加载两个文件,并对它们异步执行相同的操作。我的代码运行良好,因为我能够加载文件并对其执行操作。但是,我编写了两次相同的函数。有没有关于如何实现异步的想法Javascript 在节点中异步读取文件,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,我试图加载两个文件,并对它们异步执行相同的操作。我的代码运行良好,因为我能够加载文件并对其执行操作。但是,我编写了两次相同的函数。有没有关于如何实现异步的想法 var arrayTest = require('./data1.json'); arrayTest.data.forEach(function(str) { var newStr = str.replace(/"[^"]*"/g, function(match) { return match.split('').reve
var arrayTest = require('./data1.json');
arrayTest.data.forEach(function(str) {
var newStr = str.replace(/"[^"]*"/g, function(match) {
return match.split('').reverse().join('');
});
console.log(newStr);
});
var arrayTest2 = require('./data2.json');
arrayTest2.data.forEach(function(str) {
var newStr = str.replace(/"[^"]*"/g, function(match) {
return match.split('').reverse().join('');
});
console.log(newStr);
});
如果要在以下情况之前合并阵列:
doJob(arrayTest.concat(arrayTest2);
更新:
正如我之前已经告诉过您的,在大多数情况下,这种“异步”流是无用的。异步流不是并行流
如果您有非常大的文件,那么真正的利润可能来自使用子进程。如果是这样,您可以收集更多信息。尝试使用节点js
fs
模块。在这种情况下,每次从readFile
(针对每个文件)调用回调时,都将执行操作
const fs=require('fs');
函数readfileasync(文件、操作){
files.forEach(文件=>{
//使用节点fs异步读取文件
fs.readFile(文件、操作);
});
}
//您的自定义函数
函数replaceString(err,str){
如果(错误)抛出错误;
var newStr=str.replace(/“[^”]*”/g,函数(匹配){
返回match.split(“”).reverse().join(“”);
});
console.log(newStr);
}
readFilesAsync(['./data1.json','./data2.json'],replaceString);
我会将其更改为类似的格式。使用承诺处理异步IO,并使用1函数,以避免代码重复
'use strict';
const fs = require('fs');
const files_paths = ['./data1.js', './data2.js'];
Promise.all(files_paths.map((path) => {
return new Promise((resolve) => {
fs.readFile(path, 'utf-8', (error, data) => {
resolve(data.split(',').map((str) => {
return str.replace(/"[^"]*"/g, (match) => {
return match.split('').reverse().join('');
});
}));
});
});
})).then((results) => {
console.log(results);
});
要异步加载文件,您可以使用
fs.readFile()
,然后使用JSON.parse()
替换同步require()
,手动解析文件。因此,这里有一个函数可以异步加载文件,然后将其解析为Javascript:
// returns a promise
loadJsonAsync(file) {
return new Promise((resolve, reject) => {
fs.readFile(file, (err, data) => {
if (err) {
reject(err);
} else {
resolve(JSON.parse(data));
}
});
});
}
注意,文件加载将是异步的。JSON解析将是同步的
然后,您可以在进行处理的函数中使用此选项:
function loadAndProcess(f) {
return loadJsonAsync(f).then(arr => {
for (let str of arr.data) {
const newStr = str.replace(/"[^"]*"/g, function(match) {
return match.split('').reverse().join('');
});
console.log(newStr);
// do something with newStr here
}
}).catch(err => {
console.log(err);
throw err;
});
}
然后可以像这样运行其中两个:
Promise.all([loadAndProcess("./data1.json"),loadAndProcess("./data2.json")]).then(data => {
// both are done here
}).catch(err => {
// error here
});
如果您希望执行JSON解析的同步代码和replace循环都是异步的,那么您必须将该代码移动到子进程,然后在完成后将结果传回主进程,因为在NodeJ中无法使同步操作在同一个进程中变为异步操作进程。您是希望减少重复代码还是希望异步?这是两件完全不同的事情。第一件事情很容易完成–只需给传递给
forEach
的函数起一个类似于任何其他函数的名称,并使用它两次。嘿@Ryan,我想让它异步。有什么建议吗ons?异步执行此操作不会给您带来任何麻烦。您希望其中的哪一部分是异步的?读取文件?还是希望其处理也是异步的?这里的其他答案向您展示了如何使文件读取异步,但是如果您希望循环是异步的,以便其他代码可以与您的循环并行运行,那么您会这样做必须创建一个子进程来处理数据。可以执行该操作并使数据成为包含两个文件和数据的数组。在这种情况下,我们应该包括承诺。请告诉我是否要添加它们。谢谢Miguel。我应该将原始函数放在您提供的异步函数中的什么位置?它是否正在运行?替换操作wi回调?在调用ReadFileAsync时,您将其作为第二个参数,如ReadFileAsync(['file1','file2',],您的函数在这里)
确保原始函数接收到两个参数,第一个是错误,第二个是数据(文件内容)显然,这不是OP想要的。他们希望他们的操作是异步的。@jfriend00很可能,OP最终会发现这个代码示例更有用。让他的代码异步是没有意义的。
Promise.all([loadAndProcess("./data1.json"),loadAndProcess("./data2.json")]).then(data => {
// both are done here
}).catch(err => {
// error here
});