运行环境:nodejs
需求:提供一个方法 getD ,此方法内调用 ajax 接口获取数据,然后对外输出
1 、异步调用,比如会同时执行 30 次 getD
2 、当第一次调用 getD ,方法内没有数据,会从 ajax 拿数据,每次拿 10 条,等待中,当拿到数据后,用一条对外提供
3 、当第二次及后续调用 getD
a 如果有前面(第一次)正在 ajax 中,则等待,当 ajax 请求拿到数据后,第二次及后续的用拿到的数据
b 如果前面没有 ajax 中,则直接使用数据
4 、当 ajax 拿到的数据用完后,重复 2-3 ,但 ajax 每次请求间隔,须相隔 2s

不知道咋写,写出的也不满足,谢谢大家
最新回复 (9)
  • InDom4月前
    引用2
    好像没啥难度?

    做一个 对象,首先需要一 or 两个锁,然后需要一 or 两个队列。

    发起 ajax 需要过一下锁,ajax 发出前锁定,ajax 成功后,锁设置过期时间 2s 。

    getD 先检查队列是否能取到,成功就返回,失败就 ajax , 如果发出就等成功,失败就把回调推入等待队列。

    ajax 成功后挨个讲结果回调给等待队列。
  • shiny4月前
    引用3
    这里要考虑一个问题,只有一个进程还是会有多个进程。如果是单进程的,直接用变量就能实现;多进程需要借助其他服务。

    PS:你的描述够详细了,ChatGPT 写出来的就已经八九不离十了。
  • zbinlin4月前
    引用4
    用 async generator 来写试试
  • nbin2008楼主4月前
    引用5
    @InDom 谢谢提供的思路,我想想
    @shiny 谢谢,单进程
  • vampuke4月前
    引用6
    let pending;
    const getId = async() => {
    if (pending) return pending;
    pending = new Promise((resolve) => {
    setTimeout(() => {
    resolve('id');
    setTimeout(() => {
    pending = null;
    }, 2000);
    }, 1000);
    });
    return pending;
    }
  • Lhcfl4月前
    引用7
    不考虑多线程:
    function makeGetD() {
    let datas = [];
    let promise = null;
    let canNext = true;
    const getD = async () => {
    if (datas.length > 0) return datas.pop();
    if (promise == null) {
    if (!canNext) return;
    canNext = false;
    setTimeout(() => (canNext = true), 2000);
    promise = new Promise(res => setTimeout(() => {
    console.log("i'm ajax"); res([1,2,3,4,5,6,7,8,9,10]);
    }, 300));
    }
    datas = await promise;
    promise = null;
    return await getD();
    }
    return getD;
    }

    getD = makeGetD();
  • Curtion4月前
    引用8
    请教大家一个问题, js,异步执行
  • nbin2008楼主4月前
    引用9
    感谢大家帮忙,没来得及看,用 2 楼的方法解决了

    const axios = require('axios');

    let dataQueue = [];
    let isFetching = false;

    async function fetchData() {
    if (isFetching) return;
    isFetching = true;
    try {
    const response = await axios.get('https://example.com/api/data'); // 替换为实际的 API 地址
    dataQueue = response.data.slice(0, 10); // 假设每次获取 10 条数据
    } catch (error) {
    console.error('Error fetching data:', error);
    } finally {
    isFetching = false;
    }
    }

    async function getD() {
    while (dataQueue.length === 0) {
    if (!isFetching) {
    await fetchData();
    }
    await new Promise(resolve => setTimeout(resolve, 100)); // 等待数据获取完成
    }
    return dataQueue.shift();
    }

    // 示例:同时执行 30 次 getD
    (async () => {
    const promises = Array.from({ length: 30 }, () => getD());
    const results = await Promise.all(promises);
    console.log(results);
    })();
  • nbin2008楼主4月前
    引用10
    @Lhcfl if (!canNext) return; 这里返回,就没有数据了
    @Curtion 55 行调用,这里不是并发,整体代码很值得学习
    谢谢楼上 v 友们的解答
  • 回复请 登录 or 快速注册
返回