0%

js异步函数同步

先看一段程序

const fs = require('fs');
var path = '/home/xuranus//';
var file_list = [
'A.json',
'B.json',
'C.json',
'D.json',
];

var arr = [];
file_list.forEach(file=>{
fs.readFile(path+file,(err,data)=>{
if(err) console.log(file,err);
else {
console.log('reading ',file)
var stu = data.toString(); //data从bin->string
stu = JSON.parse(stu);//string -> json
rows = stu.rows;
rows.forEach(element => {
if(element.pwd!=undefined)
arr.push(element.pwd);//pass
if(element.phome!=undefined)
arr.push(element.phone);//phone
if(element.email!=undefined)
arr.push(element.email.split('@')[0]);//qq
if(element.code!=undefined)
arr.push(element.code);//id\
});
}
});
});

console.log(arr.length)

该程序实现了这样一个操作:从四个json文件中读取json数组,把每个json对象的若干对象放入一个数组。为了追求性(zhuang)能(bi),没有老老实实用下标迭代,而是用了forEach,而且js的读文件IO提供的api也是回调的,众所周知js的回调函数执行是异步的,于是出现了这样一个问题:当我最后想操作arr(这里为打印出arr的长度)始终为0,因为上面的forEach函数是异步的,所以console.log()在函数执行完之前就被执行。

换句话说:无法使用异步操作处理后的数据,即Arr不知在何时被处理完。此时需要强制使这块同步:使用async模块,首先npm install async --save,然后导入,代码如下:

const fs = require('fs');
const async = require('async');

var path = '/home/xuranus//';
var file_list = [
'A.json',
'B.json',
'C.json',
'D.json',
]
var arr = [];

function unique(arr){
var hash=[];
for (var i = 0; i < arr.length; i++) {
if(hash.indexOf(arr[i])==-1){
hash.push(arr[i]);
}
}
return hash;
}

async.each(
file_list,
(file, callback) => {
fs.readFile(path+file,(err,data)=>{
if(err) console.log(file,err);
else {
console.log('reading ',file)
var stu = data.toString(); //data从bin->string
stu = JSON.parse(stu);//string -> json
rows = stu.rows;
rows.forEach(element => {
if(element.pwd!=undefined)
arr.push(element.pwd);//pass
if(element.phome!=undefined)
arr.push(element.phone);//phone
if(element.email!=undefined)
arr.push(element.email.split('@')[0]);//qq
if(element.code!=undefined)
arr.push(element.code);//id\
});
}
callback(null);
});
},
() => {
console.log('arr len',arr.length);
var outArr = unique(arr);
console.log('unique arr len',outArr.length);
var str = '';
async.each(
outArr,
(element,callback) => {
str += (element+'\n');
callback(null);
},
() => {
fs.writeFile('dic.txt',str, { 'flag': 'a' }, (err)=>{
if(err) console.log(err);
});
}
);
}
);

Disqus评论区没有正常加载,请使用科学上网