在学习 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) { // 当返回进度信息时,调用此函数 });
内容版权声明:除非注明,否则皆为本站原创文章。