Promise对象
含义
Promise 是异步编程的一种解决方案,可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,同时使得控制异步操作更加容易。
语法
实例化一个Promise对象,接受一个函数作为参数,该函数有两个回调函数作为参数,分别是resolve()和reject(),异步操作成功则回调resovle()返回成功结果,使用Promise.then()来接受成功结果,失败则回调reject()返回失败结果,使用Promise.catch()来接受失败结果
//第一步:Promise实例化,接受一个函数作为参数
const p = new Promise((resolve,reject)=>{
//第二步:该参数有两个回调函数参数resolve以及reject
/* to do something... */
//第三步:异步操作成功则返回resolve函数,失败则返回rejecth函数
if (/* 异步操作成功 */){
resolve(/* 异步操作结果 */);
} else {
reject(/* 异步操作结果 */);
}
})
p.then(res=>{
//接受异步操作成功结果
}).catch(error=>{
//接受异步操作失败结果
})
- demo
function studyPromise(value){
const p = new Promise((resolve,reject)=>{
if(value){
resolve('success');
}else{
reject('fail');
}
})
return p;
}
studyPromise().then(res=>{
console.log(res);//不打印
}).catch(error=>{
console.log(error);//fail
})
studyPromise(true).then(res=>{
console.log(res);//success
}).catch(error=>{
console.log(error);//不打印
})
因为resolve()和reject()在本轮事件中最后执行,因此resolve或reject后面存在代码会先执行
new Promise((resolve, reject) => {
resolve(1);
const value = 2;
console.log(value);
}).then(res => {
console.log(res);
});
结果是会先打印2再打印1,因此在resolve或reject前加上return
new Promise((resolve,reject)=>{
if (/* 异步操作成功 */){
return resolve(/* 异步操作结果 */);
} else {
return reject(/* 异步操作结果 */);
}
})
Promise.then()
作用
当promise对象返回resolve状态时接受结果
- demo
const p = new Promise((resolve,reject)=>{
return resolve('I am resolve')
})
p.then(res=>console.log(res));//I am resolve
采用链式写法可以使用多个then()
const p = new Promise((resolve,reject)=>{});
p.then().then().then().then()....catch();
采用链式的then,若无返回值时,会依次按顺序执行方法
const p = new Promise((resolve,reject)=>{
setTimeout(()=>resolve(1),3000);
});
p.then(res=>console.log(res))
.then(()=>console.log(2))
.then(()=>console.log(3))
.then(()=>console.log(4))
.catch();
//3秒后依次输出1,2,3,4
有返回值时后一个then方法接受前一个的返回值
const p = new Promise((resolve,reject)=>{
setTimeout(()=>resolve(1),3000);
});
p.then(res=>console.log(res))
.then(()=>{
console.log(2)
return 3
})
.then(res=>{
console.log(res);
return 4
})
.then(res=>console.log(res))
.catch();
结果:3秒后打印1接着再打印2,3,4
当then返回值是一个promise对象时,要等promise对象返回异步操作结果,如果结果为resolve才能执行下一个then,若为reject中断执行then,从而执行catch()
const p = new Promise((resolve,reject)=>{
setTimeout(()=>resolve(1),3000);
});
p.then(res=>{
console.log(res);
return new Promise((resolve,reject)=>{
setTimeout(()=>resolve(2),2000);
});
})
.then((res)=>{
console.log(res)
return new Promise((resolve,reject)=>{
setTimeout(()=>reject(new Error('fail')),1000);
});
})
.then(res=>{
console.log(4);
})
.then(res=>console.log(res))
.catch(error=>console.log(error));
结果:3秒后打印1,接着2秒后打印2,再1秒后打印Error:fail,4不打印
Promise.catch()
作用
当promise对象返回reject状态或抛出错误时接受结果
- demo
const p = new Promise((resolve,reject)=>{
return reject('I am reject')
})
const p1 = new Promise((resolve,reject)=>{
throw new Error('I am error');
})
p.catch(error=>console.log(error));//I am reject
p1.catch(error=>console.log(error));//Error: I am error
可以把错误的结果放进reject()
// 写法一
const promise = new Promise(function(resolve, reject) {
try {
throw new Error('test');
} catch(e) {
reject(e);
}
});
promise.catch(function(error) {
console.log(error);
});
// 写法二
const promise = new Promise(function(resolve, reject) {
reject(new Error('test'));
});
promise.catch(function(error) {
console.log(error);
});
因此reject方法的作用,等同于抛出错误
promise.all()
作用
将多个 Promise 实例,包装成一个新的 Promise 实例,既可以同时执行多个promise实例后操作下一步步骤
语法
Promise.all()方法接受一个数组作为参数,数组成员为promise实例,若不是则使用Promise.resolve()转化成Promise实例。
Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例
Promise.all([/*promise实例1*/,/*promise实例2*/,/*promise实例3*/...])
.then(res=>res)
.catch(error=>error)
当所有promise实例都返回resolve结果时,使用promise.all().then()接受结果,结果为一个数组,每个数组成员对应每个promise实例的resolve结果
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{resolve(1)},1000)
})
const p1 = ()=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{resolve(2)},2000)
})
}
const p2 = Promise.resolve(3);
Promise.all([p,p1(),p2]).then(res=>console.log(res));//[1,2,3]
当所有promise实例当中有一个返回reject结果时,使用promise.all().catch()接受结果,结果为第一个有返回reject的结果
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{resolve(1)},1000)
})
const p1 = ()=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{reject(2)},2000)
})
}
const p2= ()=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{reject(3)},2000)
})
}
Promise.all([p,p1(),p2()]).catch(res=>console.log(res));//2
但promise实例出现reject时想执行Promise.all().then()需要在reject的promise中做自定义catch方法处理
const p1 = new Promise((resolve, reject) => {
return resolve('hello');
})
const p2 = new Promise((resolve, reject) => {
throw 'world'
}).catch(error =>error);
Promise.all([p1, p2]).then(res => {
console.log(res);// ["hello", "world"]
})
reject的promise一定要严格按照这样格式来做
new Promise((resolve, reject) => {
throw ... //data数据
//或 throw new Error(...)
}).catch(error => error);
Promise.resolve()与Promise.reject()
Promise.resolve()与Promise.reject()接受一个参数
如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved,Promise.reject方法返回一个新的 Promise 对象,状态为reject
const p = Promise.resolve('Hello');
p.then(res=>console.log(res));//Hello
const p1 = Promise.reject('World');
p1.catch(error=>console.log(error));//World
Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve()方法。
const p = Promise.resolve();
p.then(function () {
// ...
});