JS处理并行请求的四种方式

需求

两个异步请求同时发出,两个请求都返回时再做处理

实现

这里的方法仅提供思路,只做请求成功处理

方法一

使用Promise.all
const startTime = new Date().getTime() 
function request(time) {  
    return new Promise(resolve => {  
        setTimeout(() => {  
            resolve(time) 
        }, time) 
    }) 
} 
let request1 = request(3000) 
let request2 = request(2000) 
Promise.all([request1, request2]).then(res => {  
    console.log(res, new Date() - startTime) // [ 3000, 2000 ] 3001 }) 
})

方法二

自定义状态,在回调中判断返回状态,待2个请求都有返回值时再做处理
const startTime = new Date().getTime() 
function request(time) {  
    return new Promise(resolve => {  
        setTimeout(() => {  
            resolve(time) 
        }, time) 
    }) 
} 
let state = [undefined, undefined] 
let request1 = request(3000) 
let request2 = request(2000) 
request1.then(res => {  
    state[0] = res 
    process() 
}) 
request2.then(res => {  
    state[1] = res 
    process() 
}) 
function process() {  
    if (state[0] && state[1]) {  
        console.log(state, new Date() - startTime) // [ 3000, 2000 ] 3001 
    } 
} 

方法三 generator,yield

const startTime = new Date().getTime() 
function ajax(time, cb) {  
    setTimeout(() => cb(time), time) 
} 
function request(time) {  
    ajax(time, data => {  
        it.next(data); 
    }) 
} 
function* main() {  
    let request1 = request(3000); 
    let request2 = request(2000); 
    let res1 = yield request1 
    let res2 = yield request2
    console.log(res1, res2, new Date() - startTime) // 2000 3000 3001 
} 
let it = main(); 
it.next(); 

这个地方有点问题,因为request2耗时较短,会先返回,也就是先执行it.next(2000),导致res1获得了request2的返回值

若使用co函数,则不会存在这个问题,因为co是在promise.then函数中才执行it.next(),相当于it.next()是链式调用

generator使用co函数
const co = require('co') 
const startTime = new Date().getTime() 
function request (time) {  
    return new Promise(resolve => {  
        setTimeout(() => {  
            resolve(time) 
        }, time) 
    }) 
} 
co(function* () {  
    let request1 = request(3000); 
    let request2 = request(2000); 
    let res1 = yield request1 
    let res2 = yield request2
    console.log(res1, res2, new Date() - startTime) // 3000 2000 3001 
}) 

有了co函数,就不需要生成it和执行next方法了;

co的原理其实也简单,就是递归执行next,直到done为true;
如果next返回的value是Promise,则在then函数中执行next,若不是Promise,直接执行next函数

下面是co函数的简版手写实现
function co(func) {  
    let it = func() 
    let t = it.next() 
    next() 
    function next() { 
        if (t.done) return 
        if (t.value instanceof Promise) {  
            t.value.then(res => {  
                t = it.next(res) 
                next() 
            }) 
        } else {  
            t = it.next(t.value) next() 
        } 
    } 
} 

方法四


有了generator,很容易想到async/await,毕竟async/await就是由generator实现的
// setTimeout模拟异步请求,time为请求耗时 
const startTime = new Date().getTime() 
function request (time) {   
    return new Promise(resolve => {   
        setTimeout(() => {   
            resolve(time)  
        }, time)  
    }) 
} 
(async function () {
    // 注意这里一定不能写成 await request(3000),否则就是同步执行了  
    let request1 = request(3000)  
    let request2 = request(2000)  
    let res1 = await request1
    console.log(res1, new Date() - startTime) // 3000 3001  
    let res2 = await request2
    console.log(res2, new Date() - startTime) // 2000 3005 
})() 
全部评论
async await那个其实就不是并行请求而是串行请求了
点赞
送花
回复 分享
发布于 2022-10-02 01:33 安徽

相关推荐

感觉这一周太梦幻了,就像一个梦,很不真实~~~感觉这个暑期,我的运气占了99成,实力只有百分之一4.15上午 腾讯csig 腾讯云部门,面完秒进入复试状态4.16下午 美团优选供应链部门,4.18上午发二面4.17晚上 阿里国际一面,纯拷打,面完我都玉玉了4.18下午 阿里国际二面,是我们leader面的我,很轻松~~4.18晚上 约了hr面4.19上午 hr面,下午两点口头oc4.19晚上 意向书说起来我的暑期好像一次都没挂过~~~~~难道我是天生面试圣体?----------------------------------------------------------------------六个月前,我还是0项目0刷题,当时想的是先把论文发出来再去找实习。结果一次组会,老师打破了我的幻想(不让投B会,只让投刊或者A)我拿头投啊!!!然后就开始物色着找实习,顺便做完了mit的6.s081,但是基本上还是没刷过题目-----------------------------------------------------------------------11月  一次偶然的机会,面进了某个耳机厂的手环部门,大概是做嵌入式的,用的是CPP。12月 莫名其妙拿到了国创的面试机会,0基础四天速成java基础!居然也给我面过了hhhhh,可能是面试没写题吧入职国创后的几个月,一直没活,天天搁那看剧,都快忘了还有暑期实习这回事了~~~~命运的齿轮在2.26开始转动,因为这一天美团开了,我开始慌了,因为那时的我什么都不会。lc,八股,sql全部是0进度。然后就开始了女娲补天,上班刷题,下班继续做之前的开源,顺便学一学八股。3月到现在,lc也刷到快200了,一天最多提交了47次~~~~~~~~~~八股根据别人的面经总结和博客,写了快十万字的笔记~~~~~~~~~~简历上的实习经历和开源,也努力去深挖了,写了几万字的记录~~~~~~所以面试的时候,基本上都能cover了,面试官问到的基础基本都会,不基础的我就把他往我会的地方引。结果好像还不错,基本上每个面试官评价都挺好的emmmmmmmm
投递阿里巴巴等公司10个岗位
点赞 评论 收藏
分享
2 1 评论
分享
牛客网
牛客企业服务