一 为什么要使用Promise
由于异步任务不能直接拿到结果,于是我们传一个回调(函数)给异步任务,当异步任务完成时调用回调,同时调用的时候把异步任务的结果作为回调的参数。但是该方法容易出现回调地狱,代码变得使人看不懂,因此使用Promise。
二 用法
//该bool用来帮助模拟成功或失败
let bool=false
//封装Promise
let fn=()=>{
//返回promise实例
return new Promise((resolve,reject)=>{
if(bool){
//成功执行resolve
resolve('成功');
}else{
//失败执行reject
reject('失败');
}
})
}
//注意,成功和失败的回调函数都只能接收一个参数
fn().then(data=>console.log(data),error=>console.log(error))
//bool为false,则执行失败的回调,回调的参数error的值为"失败"
三 Promise的其他API
- Promise.resolve(result)
//制造一个成功或失败
Promise.resolve(1).then(value=>console.log(value))
Promise.resolve(new Promise((resolve,reject)=>reject('制造失败'))).then(null,error=>console.log(error))
- Promise.reject(reason)
//制造一个失败
Promise.reject(2).then(value=>console.log(value),error=>console.log('失败'))
- Promise.all(array)
//等待全部成功,或者有一个失败
Promise.all([Promise.reject('err1'),Promise.resolve(1)])
.then(value=>console.log(value),error=>console.log(error))
Promise.all([Promise.resolve(1),Promise.reject('err2')])
.then(value=>console.log(value),error=>console.log(error))
Promise.all([Promise.resolve(1),Promise.resolve(2)])
.then(value=>console.log(value),error=>console.log(error))
Promise.all([Promise.reject('err3'),Promise.reject('err4')])
.then(value=>console.log(value),error=>console.log(error))
- Promise.race(array)
//等待第一个状态改变
Promise.race([Promise.reject('err1'),Promise.resolve(1)])
.then(value=>console.log(value),error=>console.log(error))
Promise.race([Promise.resolve(1),Promise.reject('err2')])
.then(value=>console.log(value),error=>console.log(error))
Promise.race([Promise.resolve(1),Promise.resolve(2)])
.then(value=>console.log(value),error=>console.log(error))
Promise.race([Promise.reject('err3'),Promise.reject('err4')])
.then(value=>console.log(value),error=>console.log(error))
- Promise.allSettled(array)
//all只要有一个失败就中断,但我们希望拿到所有结果
//allSettled等待全部promise状态改变
Promise.allSettled([Promise.reject('err1'),Promise.resolve(1)])
.then(value=>console.log(value),error=>console.log(error))
//自己模拟实现Promise.allSettled
Promise.allSettled2=(promiseList)=>{
return Promise.all(promiseList.map(promise=>promise.then((value)=>{return {status:"ok",value}},(value)=>({status:"not ok",value}))))
}
三 手写Promise.all
function all(promiseArray){
return new Promise((resolve,reject)=>{
if(!Array.isArray(promiseArray)){
return reject(new Error('传入的参数必须是数组'));
}
let res=[];
let counter=0;
for(let i=0;i<promiseArray.length;i++){
Promise.resolve(promiseArray[i]).then(value=>{
counter++;
res[i]=value;
if(counter===promiseArray.length){
return resolve(res);
}
}).catch(
e=>{
reject(new Error('失败'));
}
)
}
})
}
var promise1 = Promise.resolve(3);
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
var promise3 = 42;
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
四 手写Promise.race
function race(promiseArray){
return new Promise((resolve,reject)=>{
if(!Array.isArray(promiseArray)){
return reject(new Error('传入的参数必须是数组'));
}
for(let i=0;i<promiseArray.length;i++){
Promise.resolve(promiseArray[i]).then(value=>{
resolve(value)
}).catch(
e=>{
reject(new Error('失败'));
}
)
}
})
}
var promise1 = Promise.resolve(3);
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
var promise3 = 42;
Promise.race([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});