【问题标题】:Queue asynchronous operation which involves promises涉及承诺的队列异步操作
【发布时间】:2013-05-04 03:02:45
【问题描述】:

我需要使用队列来序列化我的异步请求。环顾四周,我发现了 Mike Bostock here 的一个小型图书馆。但是我有点困惑,因为 tp 如何将它与 promise 对象一起使用。

所以,我有大量来自用户界面的请求。

function addTask(d){
   AsyncOper(d)
      .then(function () {
             refresh()
      });
}

AsyncOper 返回一个 Promise 对象(Angular js 实现 - $q)。

我有一个 q 定义为

var q = queue(1);

如何将addTask 转为使用q

我的第一次尝试如下:

    function addTask(d){
       q.defer(request, d)
       q.awaitAll(function(error, results) { console.log("all done!"); });
    }
    function request(d, cb) {
        AsyncOper(d)
            .then(function () {
                refresh();
                cb(null, "finished "+ d);
            })
    }

但它并没有真正序列化操作,因为我看到它试图运行多个请求。是否有可能以这种方式将 promise 和 queue 结合起来,还是有更好的方法?

谢谢。

【问题讨论】:

  • 这应该可以。正如@Iain 指出的那样,文档警告不要重复调用awaitAll,但即使这样(至少在库的当前版本中)也不应该阻止它工作。似乎它必须是别的东西。注意,如果你只是想保持一个连续的队列,你不需要调用awaitAll,队列会立即开始处理作业。
  • +1 谢谢。我试过没有 awaitAll,它仍然有效。我不在乎任务完成后的最终结果,希望这样做没有害处。再次感谢
  • 这是一个非常酷的小库,但我确实认为它正遭受身份危机(它是一个队列,还是一个串行/并行任务运行器?)。这可能不是问题,但应该注意的是,如果用作无限期运行的队列,它会有一点内置的内存泄漏,因为作业的结果会永久存储,等待await(All)。跨度>
  • 再次感谢您提到内存泄漏问题。您对只有一个用例的小型库有什么建议 - 排队同步任务需要一次处理一个。主要是限制它可以运行的速率。
  • 真的什么都没想到。您现在使用的这个库非常接近您将获得的最小。如果您的作业没有返回数据,则队列将仅维护一个未绑定的稀疏数组,这不会造成太大的内存泄漏(并且取决于浏览器的实现,如果未为未定义的索引分配空间,则可能根本就没有) .但是如果你想稍微修改一下库,用一个简单的对象替换作业数组是微不足道的,你可以在完成时删除作业键。只要您尊重许可,修改和重用代码应该没问题。

标签: javascript d3.js queue queue.js


【解决方案1】:

https://github.com/mbostock/queue 说,关于 await 和 awaitAll:

This method should only be called once, after any tasks have been
deferred. If the await callback is set multiple times, or set before 
a task is deferred, the behavior of the queue is undefined.

目前,每次推迟任务后,您都会调用 awaitAll,这确实是一件很麻烦的事情。有没有一个地方可以在所有东西都排队之后等待所有的东西?如果没有,这个特别的库可能不适合你。

【讨论】:

  • 我也读过那个位,但是看着the source 似乎所有await 函数所做的都是覆盖队列耗尽时执行的回调,如果队列已经为空,则调用它.我没有立即明白为什么 OP 的代码不起作用。有什么想法吗?
  • 你是对的,从源头上看它为什么不应该工作并不明显。我只是在哲学上反对做文档说你不应该做的事情,并希望在这种情况下,反对意见可能会转化为错误修复。我要问的下一个问题是: refresh() 做什么?您是否证明 AsyncOper() 在请求实际完成之前无法解析? q 是否只有一个分配,其并行度肯定为 1?
  • 谢谢@numbers1311407。你的 cmets 真的很有帮助。我的 AsyncOper 是一系列(链)异步操作,我没有序列化其中一个。一旦我序列化了链中的所有操作,它就可以正常工作。再次感谢您的帮助。
猜你喜欢
  • 2018-11-03
  • 2017-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2016-02-27
  • 2019-01-23
相关资源
最近更新 更多