学JS的心路历程-Promise(三)

时间:2021-05-23 16:31:17

今天我们来说then一些特殊情况以及Promise.all()与Promise.race()。

我们都知道函式作为参数传入时,可以参照的方式传入,也能传入时执行拿回传值作使用:

function useReference(cb){

console.log(“useReference”);

console.log(cb());

}

function useFunctionValue(val){

console.log(val);

}

function funB(){

return“funB”;

}

useReference(funB);

useFunctionValue(funB());

但是在Promise中使用then时,要注意到:

onFulfilled或onRejected不是函式时,忽略跳过(thenorwegianstig)。

function doA(){

console.log('doA start')

return new Promise(function(resolve,reject){

console.log('doA end');

resolve(1);

})

}

function doB(){

console.log('doB');

return 10;

}

function final(value){

console.log('final');

console.log(value);

return 0;

}

//正常函式参照写法

doA().then(doB).then(final);

//doA start

//doA end

//doB

//final

//10

上面这个是一般我们把函式当参数传入时的做法,那如果在传入doB时就先执行了,会发生什么事情呢?

doA().then(doB()).then(final);

//doA start

//doA end

//doB

//final

//1

在执行then(doB())时,虽然有说到如果不是函式便会跳过,但我们知道函式的回传值也可以为函式,所以JS还是会执行它,当然最后得到的只是doB()的回传值2。

所以then(doB())会继续用fulfilled的状态,带着值1回传新的Promise物件给下个then方法。

如果真的要这样写,可以改写成这样:

doA()

.then((val)=>{

})

.then(final);

Promise.all()

前面在用Promise时都是一次进行一个任务,但如果今天需要一次执行多个任务时,像是同时发出两个ajax请求,就需要用Promise.all()。

语法如下:

Promise.all(iterable);

iterable代表可以传入一个数组或字串,一般来说都会使用数组当作参数。

Promise.all()会将数组中的值全部执行完后,才会接着执行下个then方法。这边要注意到几个规则:

数组索引值与执行顺序无关。

数组中的值如果不是Promise物件,则会自动使用Promise.resolve方法转换。

执行过程中只要数组其中一个值发生错误,会立即回传reject状态。

执行完成后会回传一个数组值。

最好每次在使用时加上错误处理。当然一般Promise也要!

让我们来看几个例子吧:

var promise1 = 42;

var promise2 = Promise.resolve(“hihi”);

var promise3 = new Promise((resolve,reject)=> {

setTimeout(()=> resolve('Im async'),1000)

});

Promise.all([promise1,promise2,promise3]).then((value)=> {

console.log(value)

}).catch((err)=> {

console.log(err.message)

});

//[42,“hihi”,“Im async”]

Promise.race()

Promise.race()的规则跟Promise.all()一样,区别在于只会回传最快完成的那个,不论最快成功或失败。

通常用于获取资源时有很多个地方,像是服务器端与自己电脑端,只需要取最快回来的就好。

var promise1 = new Promise((resolve,reject)=> {

setTimeout(()=> resolve('delay 200'),200)

});

var promise2 = new Promise((resolve,reject)=> {

setTimeout(()=> resolve('delay 1000'),1000)

});

var promise3 = new Promise((resolve,reject)=> {

setTimeout(()=> resolve('delay 2000'),2000)

});

Promise.race([promise1,promise2,promise3]).then((value)=> {

console.log(value)

}).catch((err)=> {

console.log(err.message)

});

//delay 200

到这边Promise就告一段落了,希望大家看完后有比较了解。

如果有错误及来源未附上也欢迎留言指正,那么我们明天见(aichi-kaigo)。