我正在寻找关于扩展关于链式ajax请求的a previous accepted answer的建议。
提出了以下异步链解决方案来对3条ajax请求进行排序:
var step_3 = function() {
c.finish();
};
var step_2 = function(c, b) {
ajax(c(b.somedata), step_3);
};
var step_1 = function(b, a) {
ajax(b(a.somedata), step_2);
};
ajax(a, step_1);对于预先确定的少量链接ajax函数来说,这是很好的,但是对于可变数量的这样的函数来说,这并不是很好的扩展。
我尝试做了以下工作,但由于我承认缺乏javascript的专业知识,我似乎遇到了范围界定问题:
var asynch = function (options, fNext) {// do something asynchronously}
var chain = {f:[]} // chain of asynchronous functions
var args = function(n){ //return arguments to feed n'th asynch function }
for (n=0;n<N;n++)
{
var a = args(n);
var ftmp = n==N-1? function(){} : chain.f[n+1]
chain.f[n] = function () {asynch(a, ftmp)}
}
chain.f[0]() // initiate asynchronous chain发布于 2013-12-19 22:00:40
对于for循环来说,这是一个非常常见的作用域问题。for循环的每一次迭代都使用与父函数相同的本地作用域,这意味着异步发生的任何事情最终都将访问循环的最后一个值,而不是定义时的值。以这个小提琴为例:http://jsfiddle.net/GAG6Q/而不是asynch被调用9次,它只被调用一次,值为9。您可以通过为循环内部提供一个私有范围来修复它。您还需要将chain.f[n+1]包装在一个函数中,这样就不会试图将未定义的赋值分配给ftmp。
http://jsfiddle.net/GAG6Q/1/
var N = 10;
var asynch = function (options, fNext) {
console.log(options);
setTimeout(fNext,500);
}// do something asynchronously}
var chain = {f:[]} // chain of asynchronous functions
var args = function(n){return n;} //return arguments to feed n'th asynch function }
for (n=0;n<N;n++)
{
(function(n){
var a = args(n);
var ftmp = n==N-1? function(){} : function(){chain.f[n+1]();};
chain.f[n] = function () {asynch(a, ftmp)}
})(n);
}
chain.f[0]() // initiate asynchronous chain发布于 2013-12-19 21:27:36
异步循环是一个痛苦的屁股。经验法则是,如果您想手工完成这些操作,则需要将for循环重写为递归函数。
function sequence_synchronous(steps){
for(var i=0; i<steps.length; i++){
steps[i]();
}
return;
}
function sequence_async(steps, callback){
var i = 0;
var next_step = function(){
if(i >= steps.length){
callback();
}else{
steps[i](function(){
i++;
next_step();
});
}
}
next_step();
}请注意,这并不是在调用第一个回调之前构建一个大回调链--我们所做的只是将传统的for循环转换为连续传递样式。
不过,我强烈建议找一个库来帮你做这件事。
https://stackoverflow.com/questions/20691858
复制相似问题