Promise
- 回调地狱
“说白了就是异步里面套了一个异步 ,异步依赖于上一个异步的结果 就得嵌套进去
”
const fs = require("fs");
fs.readFile('./data/a.txt', function (err, data) {//字符串二进制转中文可以在这的第二个参数设置为'utf8'
if (err) {
// return console('读取失败')
//抛出异常
// todo 1.阻止程序的执行
// todo 2.把错误消息打印到控制台
throw err
}
console.log('xxx', data.toString())
})
fs.readFile('./data/b.txt', function (err, data) {//字符串二进制转中文可以在这的第二个参数设置为'utf8'
if (err) {
throw err
}
console.log('xxx', data.toString())
})
fs.readFile('./data/c.txt', function (err, data) {//字符串二进制转中文可以在这的第二个参数设置为'utf8'
if (err) {
throw err
}
console.log('xxx', data.toString())
})
// 输出顺序取决于文件的大小 其实也不一定 底层是一个多线程的东西 不一定谁先谁后 无法保证顺序
- 通过回调嵌套的方式来保证顺序
const fs = require("fs");
fs.readFile('./data/a.txt', function (err, data) {//字符串二进制转中文可以在这的第二个参数设置为'utf8'
if (err) {
// return console('读取失败')
//抛出异常
// todo 1.阻止程序的执行
// todo 2.把错误消息打印到控制台
throw err
}
console.log('xxx', data.toString())
fs.readFile('./data/b.txt', function (err, data) {//字符串二进制转中文可以在这的第二个参数设置为'utf8'
if (err) {
// return console('读取失败')
//抛出异常
// todo 1.阻止程序的执行
// todo 2.把错误消息打印到控制台
throw err
}
console.log('xxx', data.toString())
fs.readFile('./data/c.txt', function (err, data) {//字符串二进制转中文可以在这的第二个参数设置为'utf8'
if (err) {
// return console('读取失败')
//抛出异常
// todo 1.阻止程序的执行
// todo 2.把错误消息打印到控制台
throw err
}
console.log('xxx', data.toString())
})
})
})
//b必须放在a的回调函数中
- 为了解决以上编码方式带来的问题(回调地狱嵌套)、在es6中新增了一个API:
Promise

- 刚开始的时候就是pending正在执行状态 状态只能变成其中一种
- 在es6中新增了一个API、promise是一个构造函数
// todo 在es6中新增了一个API、promise是一个构造函数
const fs = require('fs')
// 1.创建Promise容器 给别人一个承诺
console.log(1)
// promise一旦创建,就会立即执行里面(function中)的代码 承诺本身不是异步的 承诺里面的函数(任务)是异步的
var p1 = new Promise(function(resolve,reject){//形参
//p1 是一个实例 new promise得到的
console.log(2)
fs.readFile('./data/a.txt','utf8',(err,data)=>{//promise是一个容器 但是往往里面封装了一个异步任务
if(err){
// 失败了 承诺容器中的任务失败了
// console.log(err)
reject(err)//把容器的pending状态改为reject 要告诉别人 不要自己抛出了
}else{
// 成功了 承诺容器中的任务成功了
console.log(3)
// 也就是说这里调用的resolve方法实际上就是then方法中传递的那个function
resolve(data)//把容器的pending状态改为resolved 回调函数 在这里调用
}
})
})
console.log(4)
// p1就是承诺
// 当p1 成功了,然后做指定的操作
// then 当中接受的function 就是容器中的resolve函数
p1.then(function(data){
console.log(data)//定义 这个data 就是resolve中的data
},function(err){
console.log('输出文件失败',err)//reject方法
})
- 建立3个promise实例
p1,p2,p3
p1.then(function(data){
console.log(data)
// 当p1读取成功的时候,当前函数的return 的结果就可以在后面的then中 function接受到
// 当你return 123 后面就接受到 123 没有return 就会返回undefined
//当return 一个promise对象的时候,后面的then中方法的第一个参数会作为p2 的resolve
return p2
},function(err){
console.log('输出文件失败',err)//reject方法
}).then(function(data){//p2 的resolve
console.log(data)
return p3
}).then((data)=>{//p3的resolve
console.log(data)
})//链式调用
- 封装promise版本的readfile
// todo 在es6中新增了一个API、promise是一个构造函数
const fs = require('fs')
function pReadFile(filePath){
return new Promise(function(resolve,reject){//形参
// console.log(2)
fs.readFile(filePath,'utf8',(err,data)=>{
if(err){
// 失败了 承诺容器中的任务失败了
// console.log(err)
reject(err)//把容器的pending状态改为reject
}else{
// 成功了 承诺容器中的任务成功了
// console.log(3)
// 也就是说这里调用的resolve方法实际上就是then方法中传递的那个function
resolve(data)//把容器的pending状态改为resolved
}
})
})
}
pReadFile('./data/a.txt')
.then(function(data){//promise对象才可以then
console.log(data)
return pReadFile('./data/b.txt')//这个方法一调用就会return 一个promise对象
})
.then(function(data){
console.log(data)
return pReadFile('./data/c.txt')
})
.then(function(data){
console.log(data)
})