nodejs异步编程

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');

你可能感兴趣的:(nodejs,nodejs,异步)