【发布时间】: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