promise
1 ,背景
Promise 是异步编程的一种解决方案,Promise 是一个对象,从它可以获取异步操作的消息
2,特点
(1)对象的状态不受外界影响。
Promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise
对象的状态改变,只有两种可能:从pending
变为fulfilled
和从pending
变为rejected
。
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)
3,缺点
(1)无法取消Promise
,一旦新建它就会立即执行,无法中途取消。
(2)如果不设置回调函数,Promise
内部抛出的错误,不会反应到外部。
(3)当处于pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
4,用法
1 基本用法
let p1 = () => {
return new Promise((resolve, reject) => {
console.log('3秒钟后,p1函数结束');
setTimeout(() => {
//返回Promise
resolve(p2())
}, 3000)
})
};
let p2 = () => {
return new Promise((resolve,reject)=> {
console.log('p1结束,现在是第二个任务了!');
resolve({key: 2, content: "第二个任务结束"})
})
};
p1().then((res) => {
console.log(res);
p2().then((res2) => {
console.log(res2);
//返回Promise
return new Promise((resolve ,reject)=> {
console.log('开始第三个任务,这个任务是继续第二个的异步。');
setTimeout(()=>reject({key:3,content:"第三个任务报错!"}),2000)
})
}).catch((error)=>console.log(error));
});
结果:
3秒钟后,p1函数结束 -------promise创建后立即执行
----- console.log(res);
p1结束,现在是第二个任务了!
{key: 2, content: "第二个任务结束"}
------console.log(res2);
p1结束,现在是第二个任务了!
{key: 2, content: "第二个任务结束"}
--------在resolve后调用catch无效,无法抛出错误,因为状态已经改变
开始第三个任务,这个任务是继续第二个的异步
注意点: promise是个对象 一定要return出来, Promise对象上才有then、catch回调和 2个参数 resolve rejecte
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise
// Hi!
// resolved
上面代码中,Promise 新建后立即执行,所以首先输出的是Promise
。然后,then
方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved
最后输出。
2 升级用法:
a )Promise.prototype.then()
then
方法可以接受两个回调函数作为参数。第一个回调函数是Promise
对象的状态变为resolved
时调用,第二个回调函数是Promise
对象的状态变为rejected
时调用。这两个函数都是可选的,不一定要提供。它们都接受Promise
对象传出的值作为参数。
采用链式的then
,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise
对象(即有异步操作),这时后一个回调函数,就会等待该Promise
对象的状态发生变化,才会被调用。
b )Promise.prototype.catch()
是.then(null, rejection)
或.then(undefined, rejection)
的别名,用于指定发生错误时的回调函数。
c ) p=promise.all([a(),b()]).then().catch() //必须一起执行且都成功,只返回第一个错误状态
(1)只有a,b的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时a,b的返回值组成一个数组,传递给p
的回调函数。
(2)只要a,b之中有一个被rejected
, p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
d)Promise.allSettled([a(),b()]).then().catch() //返回所有的请求状态 并确保请求结束
获取所有入参的异步操作的所有结果,知道这些异步操作是否全部结束
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: -1 }
// ]
e) p=promise.race([a(),b()]).then().catch() //谁跑的快用谁的值
Promise.race()
总是返回第一个结果值(resolved/reject
)那样,这个方法返回的是第一个 成功的 值。
只要有其中一个promise实例是rejected,就会直接走catch方法--结束。并且catch中只会返回第一个变成rejected的promise的错误
只要a,b之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数。
f) Promise.any([a(),b()]).then().catch()
只要参数实例有一个变成fulfilled
状态,包装实例就会变成fulfilled
状态;如果所有参数实例都变成rejected
状态,包装实例就会变成rejected
状态。
g) Promise.prototype.finally()
promise.then(result => {···}).catch(error => {···}).finally(() => {···});
不管promise
最后的状态,在执行完then
或catch
指定的回调函数以后,都会执行finally
方法指定的回调函数
finally的回调函数不接受任何参数,
方法里面的操作,是与状态无关的,不依赖于 Promise 的执行结果。
p就是一个promise对象 才有then方法
let p=new Promise((resolve,reject)=>{
resolve('成功')
})
p.then(resolve=>{
console.log(resolve)
},reject=>{
console.log(reject)
})
let p=function(){
return new Promise((resolve,reject)=>{
resolve('成功')
})
}
p是个函数 不是个对象 p()才是一个对象(因为有return,返回出来promise对象)
p().then(resolve=>{
console.log(resolve)
},reject=>{
console.log(reject)
})
var a=0;
let p1=function(){
return new Promise((resolve,reject)=>{
a++;
resolve(a);
})
}
let p2=function(){
return new Promise((resolve,reject)=>{
a+=2;
resolve(a);
})
}
let p3=function(){
return new Promise((resolve,reject)=>{
a+=3;
resolve(a);
})
}
p1().then(resolve=>{
console.log(resolve)
return p2();//这个return是为了后面的then
}).then(resolve=>{
console.log(resolve)
return p3();//这个return是为了后面的then
}).then(resolve=>{
console.log(resolve)
})
//136