node使用promise替代回调函数

在学习 Node.js 过程中接触到了如何使用 async 来控制并发(使用 async 控制并发)

async 的本质是一个流程控制。其实在异步编程中,还有一个更为经典的模型,叫做 Promise/Deferred 模型(当然还有更多相关解决方法,比如 eventproxy,co 等,到时候遇到在挖坑)

首先,我们思考一个典型的异步编程模型,考虑这样一个题目:读取一个文件,在控制台输出这个文件内容

var fs = require('fs');
fs.readFile('1.txt', 'utf8', function (err, data) {
  console.log(data);
});

看起来很简单,再进一步: 读取两个文件,在控制台输出这两个文件内容

var fs = require('fs');
fs.readFile('1.txt', 'utf8', function (err, data) {
  console.log(data);
  fs.readFile('2.txt', 'utf8', function (err, data) {
    console.log(data);
  });
});

要是读取更多的文件呢

var fs = require('fs');
fs.readFile('1.txt', 'utf8', function (err, data) {
  fs.readFile('2.txt', 'utf8', function (err, data) {
    fs.readFile('3.txt', 'utf8', function (err, data) {
      fs.readFile('4.txt', 'utf8', function (err, data) {
        // ...
      });
    });
  });
});

这就是传说中的 callback hell,可以使用 async 来改善这段代码,但是在本例中我们要用 promise/defer 来改善它

promise 基本概念

首先它是一个对象,它和 javascript 普通的对象没什么区别,同时,它也是一种规范,跟异步操作约定了统一的接口,表示一个异步操作的最终结果,以同步的方式来写代码,执行的操作是异步的,但又保证程序执行的顺序是同步的

1. promise 只有三种状态,未完成,完成 (fulfilled) 和失败 (rejected)

2. promise 的状态可以由未完成转换成完成,或者未完成转换成失败

3. promise 的状态转换只发生一次

promise 有一个 then 方法,then 方法可以接受 3 个函数作为参数。前两个函数对应 promise 的两种状态 fulfilled, rejected 的回调函数。第三个函数用于处理进度信息

为了理解它,一些重要原理必须记牢:.then() 总是返回一个新的 promise,如下面代码:

var promise = readFile()
var promise2 = promise.then(readAnotherFile, console.error)

这里 then 的参数 readAnotherFile, console.error 是代表异步操作成功后的动作 onFulfilled 或失败后的动作 OnRejected,也就是说,读取文件成功后执行 readAnotherFile 函数,否则失败打印记录错误。这种实现是两个中只有一种可能

也可以理解为:

promiseSomething().then(function (fulfilled) {
  // 当 promise 状态变成 fulfilled 时,调用此函数
}, function (rejected) {
  // 当 promise 状态变成 rejected 时,调用此函数
}, function (progress) {
  // 当返回进度信息时,调用此函数
});

      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/439.html