2013-05-04 52 views
0

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

所以,我有很多来自用户界面的reqs。

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

AsyncOper返回一个promise对象(angular js implementation - $ 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); 
      }) 
    } 

但它不是真正的序列化操作,因为我看到它试图运行多个请求。是否有可能将承诺和排队结合起来,还是有更好的办法?

谢谢。

+1

这应该工作。正如@Iain指出的那样,文档警告不要反复调用'awaitAll',但即使如此(至少在当前版本的库中)也不应该阻止它的工作。似乎它一定是别的东西。请注意,如果您只想保持连续队列,则不需要调用'awaitAll',队列将立即开始处理作业。 – numbers1311407 2013-05-04 04:38:09

+0

+1谢谢。我尝试不用等待,它仍然有效。我不关心任务完成后的最终结果,并希望这样做没有害处。再次感谢 – bsr 2013-05-04 13:00:29

+0

这是一个非常酷的小型库,但我认为它正在遭受身份危机(是一个队列还是一个串行/并行任务运行者?)。这可能不是问题,但应该注意的是,如果用作无限期运行的队列,它会有内存泄漏,因为作业的结果会永久存储,等待“await(All)” 。 – numbers1311407 2013-05-04 15:49:59

回答

2

https://github.com/mbostock/queue说,大约等待和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。在排好所有东西之后,你有没有可以全部等待的地方?如果不是,这个特别的图书馆可能不适合你。

+0

我也读了这一点,但看着[源](https://github.com/mbostock/queue/blob/master/queue。js#L69)似乎所有的'await'函数都会覆盖队列消耗时执行的回调函数,并在队列已经为空时调用它。我没有立即看到为什么OP的代码不起作用。有什么想法吗? – numbers1311407 2013-05-04 03:43:03

+0

你是对的,从源头上看不明白为什么它不起作用。我只是在哲学上反对做文档说你不应该做的事情,并希望在这种情况下,这种反对意见可能会转化为错误修正。接下来的问题是:refresh()会做什么?你是否证明在请求实际完成之前,AsyncOper()不能解析? “q”只有一个赋值,它肯定有1的并行性? – Iain 2013-05-04 05:01:49

+0

谢谢@ numbers1311407。你的意见真的有帮助。我的AsyncOper是一系列(链)异步操作,我没有序列化其中的一个。一旦我序列化链中的所有操作,它都可以正常工作。再次感谢您的帮助。 – bsr 2013-05-04 13:03:03