异步接口返回如何顺序执行?

问题描述

后台会主动推消息到前端,每一个消息需要请求一个接口D,然后再做后续的操作。
按照执行先后应该是:

消息A --> 请求D --> 处理A,然后 消息B --> 请求D --> 处理B

但是由于消息A和消息B有时推送间隔非常短,会出现下面的情况:

消息A,消息B --> 请求D两次 --> 处理B,处理A

最后导致应该是处理B以后的结果变成了处理A以后的结果。

怎么样能使这两个过程分离开来?

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

websocket推送消息过快,但是需要对每条信息做相应处理,且处理之前有异步过程(请求D)

尝试过 Promise.all() / Promise.race() / process.nextTick()

阅读 6.6k
4 个回答

Promise.all()用了有啥问题

const allInOrder = (promises, thenForEach) => {
  let sequence = Promise.resolve();

  promises.forEach(function(request) {
    sequence = sequence.then(function() {
      return request.then(thenForEach);
    });
  });
};

测试一下

let timeConsumingFunc = param => new Promise(
  (resolve) => {
    let timeout = Math.random() * 5000;
    console.log(`task ${param} will be resolved in ${timeout}ms`);
    setTimeout(() => {
      console.log(`${param} resolved`);
      resolve(param + 10);
    }, timeout);
  }
);

allInOrder(
  [timeConsumingFunc(1), timeConsumingFunc(2), timeConsumingFunc(3)],
  d => {
    return new Promise(function(resolve) {
      console.log(d);
      resolve();
    });
  }
)

你的问题我遇到过,我在React中的解决方案是,先拿到A消息回来的数据,然后去setState设置状态,在setState的回调函数中继续发送请求给服务器端获取数据,再进行操作。
如果是原生的JS我给你的思路是,先将A消息的结果在promise中处理,处理完了之后使用.then()方法中return出来,然后保存,然后再去处理B的消息,重复上面的套路。
关键是,你两个消息有关联吗,必须有处理的顺序吗? 感觉问题问的很含糊。

可以定义一个初始时间firstTime,每次推送消息的时候,获取当前时间currentTime和firstTime作对比,小于一个值(也就是间隔太短),就延时执行请求D,同时赋值currentTime给firstTime。我觉得比较好的方案是节流去处理,但是你这里说了必须处理每条数据,节流也就不太合适。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题