nodejs异步编程,老生常谈。今天总结一下,算是巩固学习吧。
以读文件为例,同步编程这么写:
var fs = require("fs");
var fileContent = fs.readFileSync('sync.js','utf8');
console.log(fileContent);
console.log("something else");
异步编程咋整?回调函数伺候之:
var fs = require("fs");
fs.readFile('async.js','utf8',function(err,data){
if(!err) {
console.log(data);
}
});
console.log("something else");
回调函数太棒了,程序可以异步了。不过回调这东西有点好过头了,当回掉函数嵌套太多时候,程序写起来相当烦人。我想每个人都知道回调地狱(callback hell)。
javascript这个又爱又恨的东西这几年发展很快,投入的很大精力去改进的东西很多东西都是为了避免回调地狱。到现在(2016-5-17),es7草案已经提出,下面我们就以es7的视野来总结一下如何避免callback hell来异步编程。
- 模块化代码
- 使用生成器
- 使用promise
- 使用时间驱动编程
- 使用Async.js
模块化代码
模块化代码其实就是将回调函数名个名字,使用回调函数时候仅仅使用名字,回掉函数的实现定义在其他地方。
这样的代码:
var fs = require("fs");
fs.readFile('async.js','utf8',function(err,data){
if(!err) {
console.log(data);
}
});
可以写成这样的:
var fs = require("fs");
fs.readFile('async.js','utf8',fileContent);
function fileContent(err,data) {
if(!err) {
console.log(data);
}
}
使用generator
这里暂时使用co模块提供的generator功能:
"use strict";
var fs = require('fs');
var co = require('co');
co(function* () {
var file1 = yield readFile('demo.js');
console.log(file1);
console.log("I am after file read even though its Async");
});
function readFile(filename) {
return function(callback) {
fs.readFile(filename, 'utf8', callback);
};
}
使用promises
es5提出了promise概念。可以使用Q库或者Bluebird库提供的promise功能:
var Promise = require('bluebird');
// Converts all function of 'fs' into promises.
var fs = Promise.promisifyAll(require('fs'));
fs.readFileAsync('file.js','utf8')
// 'then' when result comes.
.then(function(data) {
console.log(data);
})
//'catch' when error comes.
.catch(function(err) {
console.log(err);
});
使用事件驱动
EventEmitter模块提供了一些关于事件操作的方法,便于编写事件驱动的程序:
var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();
var fs = require('fs');
// Event to read file - generic function.
emitter.on('start_read',function(file_name) {
console.log("Started Reading file....\n\n");
fs.readFile(file_name, 'utf8', function (err,data) {
if (err) {
console.log("Error happens.");
} else {
console.log("File data", data);
}
});
});
// Let's read some file.
emitter.emit('start_read','env.json');
emitter.emit('start_read','envConfig.js');
来源:CSDN
作者:bdss58
链接:https://blog.csdn.net/bdss58/article/details/51439831