JS 连续发送多个请求 Promise.all() Promise.race() - Kaiqisan

**JS 连续发送多个请求 Promise.all() Promise.race() **

ヤッハロー、Kaiqisanすうう、一つふつうの学生プログラマである,昨天在写项目的时候遇到一个问题,就是在批量删除文件的时候会弹出很多的提示框,待我查看代码之后,才发现是因为这批量删除操作是通过迭代循环并多次走的请求路由导致的,每删除一个文件就弹出一个 “删除成功”,这样会导致用户体验很差。本来想找后端的人沟通一下,麻烦再写一个批量删除的路由,但是,我没有这么做,我接这个项目的目的就是为了学习的,又想到自己对异步请求这方面知识的认知还是比较薄弱的,为了提升自己,我决定自己通过前端的手段解决这个问题。
下面的代码是原先的问题代码!

this.arr.forEach(item => {
    
    
	// 请求发送正文 
})

我希望目前的异步函数能够在全部执行完毕之后获取一个统一返回,所以使用Promise.all和Promise.race()是最贴合当前的需求的。下面是一个Promise.all的最标准的格式。

Promise.all()

Promise.all([a1, a2, a3, a4]).then(res => {
    
    
    
}).catch(err => {
    
    
    
})

Promise.all()必须传入数组,因为这里的需要默认希望您处理多个异步方法,里面的成员必须是格式规范的Promise对象,否则无法获得返回

let a1 = new Promise((resolve, reject) => {
    
    
    .....
    resolve()
})

最后如果全部的异步方法安然无恙地执行完成了,最后走then里面的方法,返回一个res,它是一个数组,记录了所有的Promise的返回值(Promise使用resolve()返回值),返回值的位置是按部就班的,在传入处的第一个Promise成员返回值在res数组的第一个成员中,在传入处的第二个Promise成员返回值在res数组的第二个成员中,以此类推。

但是

如果在运行这一些异步方法的时候,其中一个方法出了异常,走了reject()线,这会导致Promise.all()整个方法立马结束并输出出故障的Promise的返回值并走catch路线,执行里面的方法。这个err就是故障线返回值。

Promise.race()

它在格式和执行流程上和上面的Promise.all()没有任何差异,唯一差异就存在于走then线路的输出值res,在Promise.all()中输出值的排列是按部就班的,但是这里不是,它这里是需要比较异步执行速度的,只输出第一个被执行完成的Promise()的返回值,如果第一个被执行完成的Promise以resolve()形式返回,就走then路线,反之走catch路线,第一个Promise执行完成之后再也不会执行后面的Promise。

参考源码

let a1 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve(10)
    }, 100)
})
let a2 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve(12)
    }, 3000)
})
let a3 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve(14)
    }, 1000)
})
let a4 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve(16)
    }, 2000)
})

Promise.all([a1, a2, a3, a4]).then(res => {
    
    
    console.log(res) // [10, 12, 14, 16]
}).catch(err => {
    
    
    console.log(err)
})

Promise.race([a1, a2, a3, a4]).then(res => {
    
    
    console.log(res) // 10
}).catch(err => {
    
    
    console.log(err)
})

其他写法

适合一些需要配合迭代的参数并批量执行的类似的异步代码的方法,可以大大节省代码量。这也是我在当前项目采用的方法

Promise.all(this.arr.map((item, i) => {
    
     // map方法迭代之后整合Promise对象为数组
    return new Promise((resolve, reject) => {
    
    
        ....resolve()
        ...reject()
    })
})).then(res => {
    
    
    //
}).catch(err => {
    
    
    //
})

总结

Promise.all()比Promise.race()更加实用,多用于批量发送请求。

解决了这个问题之后,虽然在时间花费上,比直接和后端人员沟通要来得多,但是我学到了新的知识,对异步请求有了更深的印象,再加上我写了这篇博客,又复习了这个知识点。日后,我能够更加熟练地使用这个方法。如果我出去实习啥也没学到,那我不就亏死了,拿的钱还远不如别的公司员工多,还没学到什么,那怎么说得过去呢?!

猜你喜欢

转载自blog.csdn.net/qq_33933205/article/details/108075177