求一个同步请求队列的方法 - JavaScript(axios)

问题描述

需要向服务器不断地发起请求,获取到服务器所有的列表数据,但是不能使用循环进行请求,需要等第一次请求有结果之后再发起第二次请求,第二次请求有结果之后再发起第三次请求,以此类推...请求次数不固定,最后获取到所有的请求数据。

问题出现的环境背景及自己尝试过哪些方法

  1. 尝试使用过while循环最后以失败告终
  2. 尝试使用过递归,但是性能不太好,会导致爆栈(内存泄漏)

你期待的结果是什么?实际看到的错误信息又是什么?

在执行完某方法后,可以返回所有请求数据的结果。并且可以捕获请求过程中的错误。如果请求过程中发生错误,停止请求。

阅读 8.1k
7 个回答

最终解决方案,也是在git上找到的包,节选了一段人家的代码

const generate = (p) => {
  p = p || Promise;
    return function(condition, action, ctx) {
        var whilst = function(data) {
            try {
                if (ctx == null) ctx = this;
                if (!condition.call(ctx, data)) return p.resolve(data);
                return p.resolve(action.call(ctx, data)).then(whilst);
            } catch(e) {
                return p.reject(e);
            }
        };
        return whilst();
    };
}

使用方法如下:

let whileSend = generate();
let arr = [];
let totalCount = 0;
whileSend(() => {
  return !(arr.length === totalCount);
}, async () => {
  let tableData = await axios.post("请求地址...",query);
  query.pageInfo.page++;
  let {list,totalCount:allNum} = tableData.data.result;
  arr = [...arr,...list];
  totalCount = allNum;
  return arr;
}).then((res) => {
  //    处理成功回调函数
  console.log("成功",res);
}).catch((error) => {
  console.log(error.message || error);
});

同事使用async/await也实现了一个

let sendWhile = async (arr) => {
    let valArr = [...arr];
    while(valArr.length){
        try {
          let res = await this[methodName](valArr.shift())
        } catch (error) {
          valArr=[]
        }
    }
}

最终选择方案选择了第一种

递归是一种方案,因为你要判断请求结果再执行第二次。
另一种就只能靠后端了,前端一直循环,后端根据需求返回结果,出错结束循环。

写一个简单的伪代码,大概逻辑我觉得应该是这样的

let index = 0

// 异步请求
function ajaxData(){
    // 请求获取数据的逻辑
}

function fetch(){
    index++
    ajaxData()
        .then(fetch) // 请求成功后发起下一次请求
        .catch(err=>{
            // 处理异常
        })
}

fetch()

async/await +1

import { Observable } from "rxjs";

function GetPromise() {
  return new Promise(resolve => {
    const time = Math.floor(Math.random() * 5) + 1;
    setTimeout(() => {
      console.log(time);
      resolve(time);
    }, time * 1e3);
  });
}

Observable.range(0, 3)
  .concatMap(t => Observable.fromPromise(GetPromise()))
  .bufferCount(3)
  .subscribe(t => {
    console.log(t);
  });

Observable.defer(() => Observable.fromPromise(GetPromise()))
  .repeat()
  .subscribe(t => {
    console.log(t);
  });
//试试这样 注意return
function a(){
    return axios.get()
}
function b(){
    return axios.post()
}
function c(){
    return axios.post()
}
a().then(b).then(c).catch((err)=>{console.log(err.message)})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏