【发布时间】:2013-12-14 13:31:53
【问题描述】:
我有一长串要按顺序执行的异步函数。所以我使用了 Promise 来创建 Promise 队列。不幸的是,在 Linux 上的 Firefox 25.0.1 上,我收到 too much recursion JavaScript 错误。它在 Mac 上的相同 Firefox 版本上运行良好,它也适用于 chrome。但我需要它在任何地方都能工作,包括 Linux。你能建议更好地实现executePromiseQueueSync函数吗?
//-----------------------------------------------------------------------------------------
function executePromiseQueueSync(queue){
var seed = $.Deferred();
var acc = seed;
for (var i = 0; i < queue.length; ++i )
{
var promise = queue[i];
acc = acc.then(promise.funct.apply(null, promise.argmnt));
}
seed.resolve();
return acc;
}
//-----------------------------------------------------------------------------------------
function someTask(){
var dfd = new jQuery.Deferred();
dfd.notify();
dfd.resolve();
return dfd.promise();
}
//-----------------------------------------------------------------------------------------
$(function(){
var promisesQueue = []
for(var i = 0; i < 200; ++i){
promisesQueue.push({funct:someTask, argmnt:[]});
}
executePromiseQueueSync(promisesQueue).then(function(){alert('done!');});
});
//-----------------------------------------------------------------------------------------
JSFiddle 示例:http://jsfiddle.net/C2YN4/4/
我目前的情况(我非常愿意接受其他建议和更正):
function executePromiseQueueSync(queue){
if (queue.length > TRESHOLD){
var i,j;
var shortQueue = []
for (i=0,j=queue.length; i<j; i+=TRESHOLD) {
temparray = queue.slice(i, i+TRESHOLD);
shortQueue.push({funct:executePromiseQueueSync, argmnt:[temparray]});
}
return executePromiseQueueSync(shortQueue);
}
var seed = $.Deferred();
var acc = seed;
for (var i = 0; i < queue.length; ++i )
{
var promise = queue[i];
acc = acc.then(promise.funct.apply(null, promise.argmnt));
}
seed.resolve();
return acc;
}
所以基本思想是制作一个promise树而不是promise链。这样我们就不会深入堆栈。
【问题讨论】:
-
为什么
promise.funct没有返回函数时会被调用?看起来你正在向.then()传递承诺,这是无效的 -
如果
someTask是同步的,为什么还要使用承诺? -
@Bergi - 您可以从 someTask() 中删除承诺,问题仍然存在。
-
是否需要使用promise?还是只是想在等待上一个函数完成的同时按顺序执行链?
-
@Bergi - 假设您想按顺序执行一些 ajax 调用。这个例子对你来说足够了吗?
标签: javascript algorithm recursion promise jquery-deferred