【问题标题】:Promise queues?承诺队列?
【发布时间】:2016-06-18 16:06:02
【问题描述】:

我有一个应用程序正在发送一个 http 请求,该请求在用户每次输入时都会返回一个承诺。我让它每 500 毫秒去抖动一次。有时我请求的 api 需要很长时间才能响应。例如,我对a 发出搜索请求,需要很长时间才能响应,但随后用户继续键入以完成a+x 的查询,该查询几乎立即解决,但a+x 的结果被先前的请求覆盖只是a

TL;DR:如果在当前解决之前调用了新的承诺,如何取消当前

【问题讨论】:

  • 代码值 1024 字。发布minimal reproducible example
  • 我正在使用vue-resource,所以我试图让这个问题尽可能与库/框架无关,以帮助其他人。
  • “几乎立即解决,但 a+x 的结果被之前的请求仅 a 覆盖” 为什么结果会被覆盖?
  • 结果被覆盖,因为我当前使用的是全局状态变量,当请求解决时它被设置为响应。
  • 您将需要使用可取消的承诺。您使用哪个库来发出 HTTP 请求?

标签: javascript http promise


【解决方案1】:

创建一个变量来计算您的请求:

var effectiveRequestNumber = 0;

function asyncRequest() {       
    var requestNumber = ++effectiveRequestNumber; // storing our request number
    doSomething().then(function(response) {
        // if the function was invoked after this request, then these two won't match
        if (effectiveRequestNumber !== requestNumber) {
            return;
        } 
        applyResponse(response); // we are fine - applying the response
    });
}

【讨论】:

  • 是的,和我写的基本一样。我倾向于记住对象,但我同时使用了序列号(如上)和对象。简单有效。
【解决方案2】:

我通常处理重叠查询的方式是我只想要最后一个结果的结果是记住可以在回调中检查的内容。

您没有引用任何难以提供帮助的代码,但这里有一个示例:

"use strict";
// NOTE: Will only run if your browser supports promises.

// Scoping function to avoid globals
(function() {
  // We keep track of the most recent promise
  var lastSomethingRequest = null;
  
  // Our function that does something async
  function doSomething(value) {
    console.log("doing request for " + value);
    
    // Start the async, remember the promise
    var p = new Promise(function(resolve) {
      setTimeout(function() {
        resolve("resolve for " + value);
      }, Math.floor(Math.random() * 500));
    });
    
    // Remember that as the most recent one
    lastSomethingRequest = p;
    p.then(function(result) {
      // Use the result only if it's the most recent
      if (lastSomethingRequest === p) {
        console.log("Use this result: " + result);
        lastSomethingRequest = null; // Release the promise object
      } else {
        console.log("Disregard outdated result: " + result);
      }
    });
  }

  // Generate 5 requests in a row that will complete in varying
  // amounts of time, where we only want the result of the last one
  for (var n = 0; n < 5; ++n) {
    doSomething(n);
  }
})();

【讨论】:

    猜你喜欢
    • 2018-11-28
    • 2014-12-29
    • 2018-11-03
    • 1970-01-01
    • 2014-03-14
    • 2015-02-18
    • 1970-01-01
    • 2017-10-22
    • 2019-05-15
    相关资源
    最近更新 更多