当node中异步读取文件(在所有的同步任务执行完成之后执行的任务)操作,需要并行执行完成后调用某函数:
const fs = require('fs'); let user = {} // 异步读取文件;文件在根目录下 fs.readFile('1.txt', 'utf-8', function(err, data) { user['name'] = data; }) fs.readFile('1.txt', 'utf-8', function(err, data) { user['age'] = data; }) // 需要等待上面的两个异步任务都执行完成后再执行该方法 function getUser() { console.log(user); }
1. 自定义函数after
/** * * @param {number} timers 需要执行的次数 * @param {function} fn 需要异步执行完成后执行的函数 */ function after(timers, fn) { return function() { if (--timers === 0) { fn(); } } } const newAfter = after(2, getUser); const fs = require('fs'); let user = {} // 异步读取文件;注意文件要在根目录下 fs.readFile('1.txt', 'utf8', function(err, data) { if (!err) { user['name'] = data; newAfter(); } }) fs.readFile('2.txt', 'utf8', function(err, data) { if(!err) { user['age'] = data; newAfter(); } }) // 需要等待上面的两个异步任务都执行完成后再执行该方法 function getUser() { console.log(user); }
2. 发布订阅模式
发布订阅模式的本质是,订阅的函数存入队列,每次发布的时候全部执行。
// 定义一个含有发布订阅功能的对象 const e = { arr: [], // 存储订阅函数 on(fn) {// 订阅函数 this.arr.push(fn); }, emit() {// 发布函数 this.arr.forEach(fn => fn()); } } e.on(function() { if(Object.keys(user).length === 2) { getUser(); } }) const fs = require('fs'); let user = {} // 异步读取文件;注意文件要在根目录下 fs.readFile('1.txt', 'utf8', function(err, data) { if (!err) { user['name'] = data; e.emit(); } }) fs.readFile('2.txt', 'utf8', function(err, data) { if(!err) { user['age'] = data; e.emit(); } }) // 需要等待上面的两个异步任务都执行完成后再执行该方法 function getUser() { console.log(user); }