已有请求函数getData,其功能为异步请求数据返回promise对象,如getData(params).then(…).catch(…)。实现一个myGetData,返回promise对象,要求加入失败重试功能,该函数内部依然使用getData实现,在getData失败一次后间隔一秒钟再重试一次,直到重试到第五次、如果全都失败了,myGetData所返回的promise为reject,只要有任意一次成功,则停止重试,知道resolve结果。
(1)假定getData的promise是一个简单的随机数例子,生成一个随机数大于10则reject,小于10则resolve:
function getData(){ let p = new Promise(function(resolve, reject){ setTimeout(function(){ var num = Math.ceil(Math.random()*20); //生成1-10的随机数 console.log('随机数生成的值:',num) if(num<=10){ console.log('符合条件,值为'+num) resolve(num); } else{ reject('数字大于10了执行失败'); } }, 2000); }) return p }(2)实现函数myGetData,也返回一个promise,但是有失败重试功能:
function myGetData(getData, times, delay) { return new Promise(function(resolve, reject) { function attempt () { getData().then(resolve).catch(function(erro) { console.log(`还有 ${times} 次尝试`) if (0 == times) { reject(erro) } else { times-- setTimeout(attempt(), delay) } }) } attempt() }) }我们通过调用myGetData来看下执行效果,是否达到五次失败内可以重试:
// 执行函数,五次重试,每隔一秒执行一次 myGetData(getData,5,1000)可以看出程序执行一次发现失败了会继续执行进行尝试。 再看一个五次都失败返回reject的结果,由于是随机的数不容易那么巧的得到五次失败的结果,我们把getData里的条件变小一点,让随机生成的数小于1才resolve,如图所示: 综上所述,带有重试功能的Promise解决啦!