关于javascript:如何通过值将数据传递到延迟的处理程序?

How to pass data by value into a deferred then handler?

我想知道如何通过值而不是引用将数据传递到jQuery Deferred对象的then处理程序中。

我有以下示例代码来说明我的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
var value;
var deferred = new $.Deferred();
var data = ["A","B","C","D"];

// add a separate call to the chain for each piece of data
for (var i = 0; i < data.length; i++) {
  value = data[i];
  deferred.then(function(response) {
    console.log(response+':'+value);
  });
}

deferred.resolve("test");

我想得到的结果:

1
2
3
4
test:A
test:B
test:C
test:D

我实际得到的结果:

1
2
3
4
test:D
test:D
test:D
test:D

似乎value的值是在执行then处理程序时计算的,而我希望在then处理程序排队时对其进行求值。

我有一个JSfiddle,希望有人可以帮忙吗?


是的..你必须围绕它创建一个闭包

1
2
3
4
5
6
7
for (var i = 0; i < data.length; i++) {
    value = data[i];
    deferred.then( function(val) {
        return function(response) {
            console.log(response+':'+val);
        }}(value));
}


试试这个:

1
2
3
4
5
6
7
8
9
10
11
var value;
var data = ["A","B","C","D"];

// add a separate call to the chain for each piece of data
for (var i = 0; i < data.length; i++) {
  value = data[i];
  $.when($.Deferred().resolve("test"), $.Deferred().resolve(value))
  .then(function(response, x) {
      console.log(response + ':' + x);
  });
}

的jsfiddle


似乎最简单的解决方案是将for循环移动到promise回调中。

1
2
3
4
5
6
deferred.then(function(response) {
  for (var i = 0; i < data.length; i++) {
     value = data[i];
     console.log(response+':'+value);
  }
});

如果你需要在你的promise处理之外进行循环,我会考虑不在循环中定义函数并使用curried函数代替:

1
2
3
4
5
6
7
8
9
10
function processResponse(val){
   return function(response){
      console.log(response,':',val);
   }
}

for (var i = 0; i < data.length; i++) {
  value = data[i];
  deferred.then(processResponse(value));
}