回调地狱与Promise解决回调地狱的问题
和异步编程有关
无法保证顺序的代码
var fs=require('fs');
fs.readFile('./data/a.txt','utf8',function(err,data){
if(err){
// return console.log('读取失败')
//抛出异常
//1,阻止程序的执行
//2,把错误消息打印到控制台
throw err
}
console.log(data)
})
fs.readFile('./data/b.txt','utf8',function(err,data){
if(err){
// return console.log('读取失败')
//抛出异常
//1,阻止程序的执行
//2,把错误消息打印到控制台
throw err
}
console.log(data)
})
fs.readFile('./data/c.txt','utf8',function(err,data){
if(err){
// return console.log('读取失败')
//抛出异常
//1,阻止程序的执行
//2,把错误消息打印到控制台
throw err
}
console.log(data)
})
通过回调嵌套的方式保证顺序
var fs=require('fs')
fs.readFile('./data/a.txt','utf8',function(err,data){
if(err){
// return console.log('读取失败')
//抛出异常
//1,阻止程序的执行
//2,把错误消息打印到控制台
throw err
}
console.log(data)
fs.readFile('./data/b.txt','utf8',function(err,data){
if(err){
// return console.log('读取失败')
//抛出异常
//1,阻止程序的执行
//2,把错误消息打印到控制台
throw err
}
console.log(data)
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
})
})
})
为了解决以上编码方式带来的问题(回调地狱嵌套),所以在ES6中新增了一个API:Promise
Promise基本语法
var fs = require('fs')
//在ES6中新增了一个API Promise//Promise 是一个构造函数
//创建Promise 容器,Promise本身不是异步,但是里面的任务是异步的//1,给别人一个承诺(异步任务)// Promise 容器一旦创建,就开始执行里面的代码var p1 = new Promise(function (resolve, reject) {
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
//把容器的Pending状态变为Rejected
//实际上就是then方法传递的那个function(err)
reject(err)
} else {
//把容器的Pending状态变为Resolved
//也就是说这里调用的resolve方法实际上就是then方法传递的那个function(data)
resolve(data)
}
})
})
//p1就是那个承诺//当p1成功了,然后(then)做指定的操作//then方法接收的function就是容器中的resolve函数
p1
.then(function(data){
console.log(data)
},function(err){
console.log('读取文件失败了',err)
})
解决回调地狱问题
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)
// 当 p1 读取成功的时候
// 当前函数中 return 的结果就可以在后面的 then 中 function 接收到
// 当你 return 123 后面就接收到 123
// return 'hello' 后面就接收到 'hello'
// 没有 return 后面收到的就是 undefined
// 真正有用的是:我们可以 return 一个 Promise 对象
// 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
//
return p2
}, function (err) {
console.log('读取文件失败了', err)
})
.then(function (data) {
console.log(data)
return p3
})
.then(function (data) {
console.log(data)
console.log('end')
})
封装Promise版本的readFile
var fs = require('fs')
function pReadFile(filePath) {
return new Promise(function (resolve, reject) {
fs.readFile(filePath, 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
pReadFile('./data/a.txt')
.then(function (data) {
console.log(data)
return pReadFile('./data/b.txt')
})
.then(function (data) {
console.log(data)
return pReadFile('./data/c.txt')
})
.then(function (data) {
console.log(data)
})