多个Promise中获取第一个成功的Promise
有这么一个需求,多张图片或者多个.mp4文件,哪一个先加载出来,就使用哪一个,加载失败的不处理。 这种需求的话就想要用到
Promise来实现
多个Promise获取第一个成功的promise
一、Promise.all 改进
Promise.all(iterable)
这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。
Promise.race(iterable)
当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
明显,Promise.all和Promise.race不行,那就行改进;
页面中渲染图片
<!-- 把onLoad和onError事件绑定到一起 -->
<!-- 图片一般都能正常加载,所以根据index来在src前面添加一个字符串,让链接加载失败 -->
<image onLoad="loadImg" onError="loadImg" data-index="{{index}}" a:for="{{imgarr}}" src="{{index % 2 ? 'aa' : ''}}{{item}}"/>
加载js
let prolist = []
//加载图片 成功或者失败
loadImg (e) {
//把每一个加载图片定义一个promise,然后push到prolist数组里面
let aPro = new Promise((resolve, reject) => {
//如果图片load成功走resolve,如果加载失败走reject
if (e.type == 'error') {
reject(e)
} else {
resolve(e)
}
})
prolist.push(aPro)
//如果prolist的长度和图片数组的长度一致时,调用函数
if (prolist.length == this.data.imgarr.length) {
this.firstProSuccess(prolist).then(res => {
console.log('res--》', res)
}).catch((e) => {
console.log('all_e', e)
})
}
},
//第一个成功的Promise
firstProSuccess (allProMise) {
//遍历promise数组,根据返回值进行判断,当成功的时候,转为reject返回,当失败的时候转为resolve继续执行。
return Promise.all(allProMise.map(item => {
return item.then(
res => Promise.reject(res),
err => Promise.resolve(err)
)
})).then(
errors => Promise.reject(errors),
val => Promise.resolve(val)
)
},
获取结果:
二、Promise.any
Promise.any(iterable)
接收一个
Promise对象的集合,当其中的一个promise成功,就返回那个成功的promise的值。
Promise.any()接收一个Promise可迭代对象,只要其中的一个promise成功,就返回那个已经成功的promise。如果可迭代对象中没有一个promise成功(即所有的promises都失败/拒绝),就返回一个失败的promise和AggregateError类型的实例,它是Error的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()是相反的。
根据MDN上的解释这个promise.any是可以来直接使用到这个需求里面的,但是很明显这个有兼容性: