javascript回调函数的泛化

时间:2012-11-30 10:10:06

标签: javascript windows-8 callback

我想创建大约10个XML HTTP请求,如下所示。我想使用i的值作为第一个“子”参考,但在执行回调之前i更改,i的值与“结果”中的网址不匹配“ 标签。我怎么能概括这个呢?

var i = 1;
WinJS.xhr({
    url: root.results[i].profile_image_url_https,
    responseType: 'blob'
}).done(function (result) {
    var imgTag = theDiv.children[1].children[0];
    var imageBlob = URL.createObjectURL(result.response, {
        oneTimeOnly: true
    });
    imgTag.src = imageBlob; //tempLocalUrl;
});

i = 2;

WinJS.xhr({
    url: root.results[i].profile_image_url_https,
    responseType: 'blob'
}).done(function (result) {
    var imgTag = theDiv.children[2].children[0];
    var imageBlob = URL.createObjectURL(result.response, {
        oneTimeOnly: true
    });
    imgTag.src = imageBlob; //tempLocalUrl;
});

5 个答案:

答案 0 :(得分:2)

典型的方法是使用额外的函数(立即执行)来捕获循环变量的当前值,例如:

var i = 1;

WinJS.xhr({
    url: root.results[i].profile_image_url_https,
    responseType: 'blob'
}).done(function (inner_i) {
  // return the actual callback
  return function (result) {
    // use `inner_i` as needed
    var imgTag = theDiv.children[1].children[0];
    var imageBlob = URL.createObjectURL(result.response, {
      oneTimeOnly: true
    });
    imgTag.src = imageBlob; //tempLocalUrl;
  };
}(i)); // <= pass outer `i`

答案 1 :(得分:1)

一般来说,你可以做两件事;

  1. 使用额外功能
  2. 使用额外的变量
  3. 在来自{}的argumentobject WinJS.xhr中,没有可以将变量复制到的范围,因此我将使用选项1:

    var i = 1;
    WinJS.xhr({
        url: root.results[ return function(i) { return i; }(i) ].profile_image_url_https,
        responseType: 'blob'
    }).done(function (result) {
        var imgTag = theDiv.children[1].children[0];
        var imageBlob = URL.createObjectURL(result.response, {
            oneTimeOnly: true
        });
        imgTag.src = imageBlob; //tempLocalUrl;
    });
    
    i = 2;
    
    WinJS.xhr({
        url: root.results[ return function(i) { return i; }(i) ].profile_image_url_https,
        responseType: 'blob'
    }).done(function (result) {
        var imgTag = theDiv.children[2].children[0];
        var imageBlob = URL.createObjectURL(result.response, {
            oneTimeOnly: true
        });
        imgTag.src = imageBlob; //tempLocalUrl;
    });
    

    更新:额外变量:

    var i = 1;
    WinJS.xhr({
        copiedVar: i,
        url: root.results[ copiedVar ].profile_image_url_https,
        responseType: 'blob'
    }).done(function (result) {
        var imgTag = theDiv.children[1].children[0];
        var imageBlob = URL.createObjectURL(result.response, {
            oneTimeOnly: true
        });
        imgTag.src = imageBlob; //tempLocalUrl;
    });
    
    i = 2;
    
    WinJS.xhr({
        copiedVar: i,
        url: root.results[ copiedVar ].profile_image_url_https,
        responseType: 'blob'
    }).done(function (result) {
        var imgTag = theDiv.children[2].children[0];
        var imageBlob = URL.createObjectURL(result.response, {
            oneTimeOnly: true
        });
        imgTag.src = imageBlob; //tempLocalUrl;
    });
    

答案 2 :(得分:0)

您可以在回调函数中增加i的值。这样,它就会在使用之后才会增加。

var i = 1;

WinJS.xhr({
    url: root.results[i].profile_image_url_https,
    responseType: 'blob'
}).done(function (result) {
    var imgTag = theDiv.children[1].children[0];
    var imageBlob = URL.createObjectURL(result.response, {
        oneTimeOnly: true
    });
    imgTag.src = imageBlob; //tempLocalUrl;

    i++;

});

答案 3 :(得分:0)

在这种情况下,可能会增加回调中的值。但解决此范围问题的一般方法是使用javascript闭包。请查看http://jibbering.com/faq/notes/closures/

答案 4 :(得分:-1)

这是一个很好的例子,我会考虑使用嵌套的联接承诺的方法:

var operations = [];
for(var i = 0; i < 10; i++) {
    operations.push(WinJS.join({
        myValue: i,
        xhr: WinJS.xhr({ url: "http://foo" }),
    }).then(function(data) {
       var yourValue = data.myValue;
       var xhrResponse = data.xhr;

       // Your processing you had before
    }));
 }

 WinJS.Promise.join(operations).done(function(operations) {
     // Done
 });

这使您有机会将事物隔离开来。含有。