首先咱们来看一个小案例javascript
data文件夹下是三个文件,咱们要写一个代码分别依次读取三个文件,使得按照 abc 的顺序输出java
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) })
这样写没法保证文件内容输出的顺序,应为读取文件函数为异步函数,那么如何解决这样的问题呢?程序员
首先咱们能够想到用嵌套的方法,后输出的放在代码最内部,先输出的放在代码最外部,可是这样一层层的嵌套使用,几个异步函数还好,当函数不少时就会显得很是不美观,并且不容易修改,还会产生一系列问题,这就产生了下面的回调地狱问题promise
下图代码就是回调地狱的一种,是否是像冲击波同样冲击着广大程序员的幼小的心灵。(豪油根~~~)markdown
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来解决回调地狱问题异步
当 p1 读取成功的时候
当前函数中 return 的结果就能够在后面的 then 中 function 接收到ide
上面那些 return 的数据实际上是没什么der用的函数
真正有用的是:咱们能够 return 一个 Promise 对象ui
当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会做为 p2 的 resolveatom
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') })