Promise简单来说就是一个容器,保存着某个未来才会结束得事件(通常为异步操作)得结果。从语法上来讲,Promise是一个对象,可以获取异步操作得消息;Promise提供了统一 得API,各种异步操作都可以用同样得方法进行处理。复制代码
1、 Promise对象有两大特点:
1)对象得状态不受外界得影响。Promise对象代表一个异步操作。有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。 Promise 对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected 。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。复制代码
2.Promise得缺点:
1)无法取消 Promise ,一旦新建它就会立即执行,无法中途取消;
2)如果不设置回调函数, Promise 内部抛出的错误,不会反应到外部。
3)当处于 pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。复制代码
3.Promise用法:
1)Promise对象是一个构造函数,用来生成Promise实例;
const KKBpromise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});复制代码
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是resolve 和reject 。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
resolve 函数的作用是,将 Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将 Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去.
Promise 实例生成以后,可以用 then方法分别指定resolved状态和 rejected状态的回调函数。 举个栗子:
KKBpromise.then(function(value) {
// success
}, function(error) {
// failure
});复制代码
then 方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为 resolved时调用,第二个回调函数是 Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受 Promise 对象传出的值作为参数。
function pros(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
pros(100).then((value) => {
console.log(value);
});复制代码
pros 方法返回一个 Promise 实例,表示一段时间以后才会发生的结果。过了指定的时间( ms 参数)以后, Promise 实例的状态变为 resolved ,就会触发 then 方法绑定的回调函数。
2)Promise新建后会立即执行。 举例说明:
let promise = new Promise(function(resolve, reject) {
console.log('Pro');
resolve();
});
promise.then(function() {
console.log('resolved');
});
console.log('Hello Promise!');
// Pro
// Hello Promise!
// resolved复制代码
Promise 新建后立即执行,所以首先输出的是 Promise 。然后, then 方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以 resolved 最后输出。
有时候在调用 resolve 或 reject 以后,Promise 的使命就完成了,后继操作应该放到 then 方法里面,而不应该直接写在 resolve 或 reject 的后面。所以,最好在它们前面加上 return 语句,这样就不会有意外。
new Promise((resolve, reject) => {
return resolve(1);
// 后面的语句不会执行
console.log('接着执行');
})复制代码
4.Promise常用得API:
1)Promise.all()这个方法返回一个新的promise对象,该promise对象在所有的promise对象都成功的时候才会触发成功,一旦有任何一个里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含所有promise返回值的数组作为成功回调的返回值,顺序跟参数的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。
let kkb1 = new Promise((resolve, reject) => {
resolve('成功了kkb1')
})
let kkb2 = new Promise((resolve, reject) => {
resolve('成功了kkb2')
})
let kkb3 = Promse.reject('失败')
Promise.all([kkb1, kkb2])
.then((result) => {
console.log(result) //['成功了kkb1', '成功了kkb2']
})
.catch((error) => {
console.log(error)
})
Promise.all([kkb1,kkb3,kkb2])
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error) // '失败'
})复制代码
2)Promise.race的使用 race和all用法类似。Promse.race方法顾名思义就是赛跑的意思,意思就是说Promise.race([kkb1, kkb2, kkb3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let kkb1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('kkb1')
},1000)
})
let kkb2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('kkb2')
}, 500)
})
Promise.race([kkb1, kb2])
.then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打印出kkb2 因为它快
})复制代码