一道工作中遇到的异步获取数据问题

本文介绍了一种使用全局ID和数组容器来确保异步请求按发送顺序返回结果的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

先看下面一段代码:

function main(n) {
    for (let i = 1; i <= n; i++) {
        request(`第${i}个请求`, getRandomTime(500, 2000));
    }
}

function getRandomTime(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function request(text, time) {
    new Promise((resolve, reject) => {
        setTimeout(() => { resolve(text) }, time);
    }).then(res => {
        console.log(res);
    })
}

main(5);

这段代码的意思为,同时发送多个请求,每个请求都需要0.5s-2s的等待时间才能返回结果。
运行上述代码,结果如下:
在这里插入图片描述
由于每个请求需要等待的时间是不确定的,进而如果我们想得到最后一次发送请求的数据,此时应该如何处理呢?(类似于实际应用中同一时间向后端请求多次,但是我们只需要得到最后一次请求的结果即可)

解决问题

解决思路:由于请求的等待时间是不确定的,所以我们无法直接得知最后一次请求将会是第几次返回。如果此时我们为每组请求都赋予一个请求id,等到它的数据返回时,那么我们就可以直接通过其请求id来判断它是第几个请求。
look my code:

let globalId = 0;
function main(n) {
    for (let i = 1; i <= n; i++) {
        request(`第${i}个请求`, getRandomTime(500, 2000));
    }
}

function getRandomTime(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function request(text, time) {
    globalId++;
    const id = globalId;
    new Promise((resolve, reject) => {
        setTimeout(() => { resolve(text) }, time);
    }).then(res => {
        if (id === globalId) {
            console.log(res);
        }
    })
}

main(5);

运行上述代码,结果如下:
在这里插入图片描述
果不其然,这次我们如愿精准捕获到最后一次请求的返回数据。

问题升级

如果我们还想要按照请求发送的顺序得到返回结果的请求,那么又该如何处理呢?
有了上面的全局id以及请求id的思路,此时我们只需要再维护一个保存数据的数组即可,让它依据请求id来记录每次返回的结果。
代码如下:

let globalId = 0;
let container = null;
let count = 0;
function main(n) {
    container = new Array(n).fill(0);
    for (let i = 1; i <= n; i++) {
       request(`第${i}个请求`, getRandomTime(500, 2000));
    }
}

function getRandomTime(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function request(text, time) {
    globalId++;
    const id = globalId;
    new Promise((resolve, reject) => {
        setTimeout(() => { resolve(text) }, time);
    }).then(res => {
        container[id - 1] = res;
        count++;
        if (count === 5) {
            console.log(container);
        }
    })
}

main(5);

运行上述代码,结果如下:
在这里插入图片描述
到此为止,一段随机时间顺序的异步请求的结果终于被我们有序的记录下来。

结语

又一道有意思的工作问题被解决了,如果大家有啥疑问或者更为精妙的解决方案,欢迎评论区留言。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值