1、概念:Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
通俗讲,Promise是一个许诺、承诺,是对未来事情的承诺,承诺不一定能完成,但是无论是否能完成都会有一个结果。
Pending 正在做。。。
Resolved 完成这个承诺
Rejected 这个承诺没有完成,失败了
Promise 用来预定一个不一定能完成的任务,要么成功,要么失败
在具体的程序中具体的体现,通常用来封装一个异步任务,提供承诺结果
Promise 是异步编程的一种解决方案,主要用来解决回调地狱的问题,可以有效的减少回调嵌套。
2、特点:
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。
3、缺点:
(1)无法取消Promise,一旦新建它就会立即执行,无法中途取消。和一般的对象不一样,无需调用。
(2)如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
(3)当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
4、基本的API(node服务器端测试promise.js)
const fs = require('fs')
// promise.js 文件
(1)new Promise
new Promise((resolve,reject)=>{
fs.readFile('./data/a.txt','utf8',(err,data)=>{
if(err){
reject(err)
}
resolve(data)
})
})
(2)PromiseObj.then(resolveFn,rejectFn)
resolveFn:就是Promise对象成功的回调处理函数,指向 resolve
rejectFn:就是Promise对象失败的回调处理函数
new Promise((resolve,reject)=>{
fs.readFile('./data/a.txt','utf8',(err,data)=>{
if(err){
return reject(err)
}
resolve(data)
})
}).then((resolveData)=>{
console.log(resolveData) // './data/a.txt' 文件中的内容
},(rejectErr)=>{
})
/*除了第一个 then ,以后的所有的 then 都是上一个 then 中的返回结果
then 接收到结果一共有三种情况:
1. 上一个 then 没有返回值,则就是 undefined
2. 上一个 then 有普通返回值:数组、数字、字符串、对象。。。
3. 上一个 then 又返回了一个新的 Promise 对象
如果是上一个 then 里面返回了一个 Promise 对象,
则这个 then 的回调处理函数就指向了上一个 then 中返回的 Promise 对象中的 resolve*/
new Promise((resolve,reject)=>{
fs.readFile('./data/a.txt','utf8',(err,data)=>{
if(err){
return reject(err)
}
resolve(data)
})
}).then((resolveData)=>{
console.log(resolveData) // './data/a.txt' 文件中的内容
},(rejectErr)=>{
}).then(data=>{
console.log(data) //undefined
return [1,2,3]
}).then(data=>{
console.log(data) //[1,2,3]
return new Promise((resolve,reject)=>{
fs.readFile('./data/a.txt','utf8',(err,data)=>{if(err){return reject(err)}resolve(data)})})}).then(data=>{console.log(data) // './data/a.txt' 文件中的内容})
(3)Promise.all()
Promise 构造函数有一个 all 方法all 方法需要接收一个数组作为参数数组中存储的多个 Promise 对象实例把多个 Promise 对象实例作为一个数组传递给 Promise.all([p1, p2, p3])然后可以通过 Promise.all() 的返回值:新的 Promise 对象再调用新的 Promise 对象的 then 方法拿结果同时 Promise.all 方法会等待所有的 异步任务执行结束了,然后将所有任务的执行结果都统一的放到一个数组中,然后传给自己的 then
function readFile(filePath, encoding) {
return new Promise((resolve, reject) => {
fs.readFile(filePath, encoding, (err, data) => {
if (err) {
return reject(err)
}
resolve(data)
})
})
}
Promise
.all([readFile('./data/a.txt', 'utf8'), readFile('./data/b.txt', 'utf8'), readFile('./data/c.txt', 'utf8')])
.then(data => {
console.log(data) // ['aaaa','bbbbb','cccccc'],每个元素是'./data/a.txt' ,'./data/b.txt','./data/c.txt'
//3个文件中的内容
})
.catch(err => {
console.log(err)
})
(4)PromiseObj.catch()
new Promise((resolve,reject)=>{
reject('出错了')
})
.catch(err=>{
console.log(err) // 出错了
})
(5)PromiseObj.resolve()
将一个值,数字,字符串...转换为Promise对象
Promise.resolve(111)
.then(data=>{
console.log(data) //111
})
(6)PromiseObj.reject()
Promise.reject('出错了')
.then(null,err=>{
console.log(err)//出错了
})
// 等价于
new Promise((resolve,reject)=>{
reject('出错了')
})
.then(null,err=>{
console.log(err) //出错了
})