编程语言
首页 > 编程语言> > JavaScript异步编程(四)之Promise并行执行和超时处理

JavaScript异步编程(四)之Promise并行执行和超时处理

作者:互联网

并行执行

或许,可能有遇到过这样的需求:

以上两种情况,都是需要在某几个接口请求完毕之后再执行另一个接口。

这个涉及到并行执行的概念,Promise.all() 刚好可以解决这个问题。

上代码:

// 仿一个ajax请求,传入一个数作为时间参数,会在对应时间之后返回一个结果
function ajax(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`完成了-${time}`)
        }, time)
    })
}

// 三个ajax执行完后,才回执行then里的代码
Promise.all([
    ajax(1000),
    ajax(1500),
    ajax(2000)
]).then(res => {
    console.log(res)
})

Promise.all() 不再做过多讲解,总结一句话就是:

Promise.all()里面的方法都执行完毕后,才会调用then回调函数里面的代码,回调函数返回的值是一个数组,分别存放Promise.all() 里方法的返回信息。

比如,上边代码,会在执行两秒后,返回结果如下:
在这里插入图片描述
错误处理

那么,如果Promise.all里的方法有一个出错了该如何处理呢?

这需要针对每一个方法单独做处理,处理后的结果会被Promise.all接收:

function ajax(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 如果参数为1500,抛出一个错误
            if (time === 1500) {
                reject(new Error('参数不能为1500'))
            }
            resolve(`完成了-${time}`)
        }, time)
    })
}

// 每个请求做catch错误处理
Promise.all([
    ajax(1000).catch(err => console.log(err)),
    ajax(1500).catch(err => console.log(err)),
    ajax(2000).catch(err => console.log(err))
]).then(res => {
    console.log(res)
})

执行结果如下:
在这里插入图片描述
在并发执行的使用中,有一种优雅的写法,就是把所有需要并行执行的接口都写在一个接口里,请求这个接口后,将返回的接口通过循环来并行执行,代码如下:

ajax('/api/urls.json')
	.then(value => {
		const urls = Object.values(value)
		const tasks = urls.map(url => ajax(url))
		return Promise.all(tasks)
	})
	.then(values => {
		console.log(values)
	})

超时处理

先来看另一个方法:Promise.race()

上代码,来看个现象:

function ajax(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`完成了-${time}`)
        }, time)
    })
}

Promise.race([
    ajax(1000),
    ajax(1500),
    ajax(2000)
]).then(res => {
    console.log(res)
})

和 Promise.all() 方法高度一致,只是将 all 换成了 race。

race 为竞赛之意,意思是说,Promise.race() 里的方法,只要有一个执行完成了,就会调用then方法里的回调函数,回调函数接收的是最早执行完的那个方法的返回信息。

所以如上代码会在执行一秒会返回:
在这里插入图片描述
那么这个方法有什么作用呢?它常常用在接口的超时处理上。

有一个接口,如果5秒内没返回结果,就报错,不再请求,可参考如下示例:


// 要7秒才能执行完
function ajax1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('7秒后我才完成')
        }, 7000)
    })
}

// 5秒后,抛出一个错误
function timeout() {
    return new Promise((resolve, reject) => {
        setTimeout(() => reject(new Error('超过5秒了')), 5000)
    })
}

Promise.race([
    ajax1(),
    timeout()
]).then(res => {
    console.log(res)
})

根据 Promise.race 特性,如果ajax1所请求的接口能在5秒内完成,then里的回调函数会返回请求所得的信息;如果5秒内不能完成,timeout将会执行然后跑出一个错误。

超时处理就完成了。

内容输出来源:拉勾大前端高薪训练营,以上文章中的内容根据老师讲课的语音和代码,结合自己的理解编辑完成。

标签:resolve,console,JavaScript,接口,并行执行,ajax,Promise,time
来源: https://blog.csdn.net/qiyuancoder/article/details/112103320