什么是promise?
首先我们来看一个小案例
data文件夹下是三个文件,我们要写一个代码分别依次读取三个文件,使得按照 abc 的顺序输出
无法保证输出顺序的代码
fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { // 抛出异常 // 1. 阻止程序的执行 // 2. 把错误消息打印到控制台 throw err } console.log(data) }) fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) }) fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) })
这样写无法保证文件内容输出的顺序,应为读取文件函数为异步函数,那么如何解决这样的问题呢?
首先我们可以想到用嵌套的方法,后输出的放在代码最内部,先输出的放在代码最外部,但是这样一层层的嵌套使用,几个异步函数还好,当函数很多时就会显得非常不美观,而且不容易修改,还会产生一系列问题,这就产生了下面的回调地狱问题
回调地狱(callback hell)
下图代码就是回调地狱的一种,是不是像冲击波一样冲击着广大程序员的幼小的心灵。(豪油根~~~)
var fs = require('fs') fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) }) }) })
接下来我们用 ES6新增的Promise来解决回调地狱问题
Promise解决
当 p1 读取成功的时候
当前函数中 return 的结果就可以在后面的 then 中 function 接收到
- 当你 return 123 后面就接收到 123
- return ‘hello’ 后面就接收到 ‘hello’
- 没有 return 后面收到的就是 undefined
上面那些 return 的数据其实是没什么der用的
真正有用的是:我们可以 return 一个 Promise 对象
当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
var fs = require('fs') var p1 = new Promise(function (resolve, reject) { fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) var p2 = new Promise(function (resolve, reject) { fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) var p3 = new Promise(function (resolve, reject) { fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) p1 .then(function (data) { console.log(data) return p2 }, function (err) { console.log('读取文件失败了', err) }) .then(function (data) { console.log(data) return p3 }) .then(function (data) { console.log(data) console.log('end') })