我正在尝试链接承诺,而不是管道,只是链接。
例如,我有这样的方法:
var execute = function(x){
// this could be an AJAX call
var d= $.Deferred();
console.log('Begin ' + x);
setTimeout(function(){
console.log('End ' + x);
d.resolve();
},500);
return d;
};
我想要多次执行这个方法,但是一个接一个。我已经创建了一个比使用eval
更好的方法,但是我对使用eval
不是很满意
var executeTimes = function(r){
var s = '';
for(var i=0;i<r;i++){
s = s + 'execute('+i+')';
if(i!==r-1)
s = s + '.then(function(){';
}
for(var i=0;i<r-1;i++){
s= s+'})';
}
eval(s);
}
这样做的想法是,执行executeTimes(3);
会得到以下输出:
Begin 0
End 0
Begin 1
End 1
Begin 2
End 2
我在这里创建了一个活的例子:http://jsfiddle.net/vtortola/Cfe5s/
最好的解决方案是什么?
干杯。
发布于 2012-11-13 02:24:17
递归在这里看起来很简洁:http://jsfiddle.net/Cfe5s/3/。
var executeTimes = function(r) {
(function recurse(i) {
execute(i).then(function() {
if(i + 1 < r) {
recurse(i + 1);
}
});
})(0);
};
您使用0
启动一个运行execute
的函数,当它完成后,您将重新开始(通过递归),但这次是使用1
。在递归之前,你必须检查是否继续:只有当递增的值仍然低于r
时才继续。
发布于 2012-11-13 02:36:46
我的方法与您的类似,但我不是连接字符串,而是嵌套函数调用:P
var executeTimes = function(r){
// The last (inner-most) step does nothing.
// just in the case we pass r <= 0
var f = function(){};
for(; r > 0 ; --r){
// Create closure with call to execute( ... ).then( ... )
f = (function(_f, _r){
return function(){ execute(_r).then(_f); };
})(f, r - 1);
}
return f;
}
它将返回一个函数,该函数的行为如您所愿。如果您这样做:
executeTimes(3)()
这将产生与您的示例相同的输出。可以很容易地修改这个示例来支持任何函数和任何最后一步(我假设函数toExec
想要接收调用的“号码”):
var executeTimes2 = function(toExec /*a function*/,
steps /*a number*/,
finalStep /*a function*/)
{
// The last (inner-most) step.
// just in the case we pass r <= 0
var f = finalStep? finalStep : function(){};
for(; steps > 0 ; --steps){
// Create closure with call to execute( ... ).then( ... )
f = (function(_f, _r){
return function(){ toExec(_r).then(_f); };
})(f, steps - 1);
}
return f;
}
所以你的函数可以像这样被调用3次:
executeTimes2(execute, 3)()
https://stackoverflow.com/questions/13349192
复制相似问题