2012-11-30 17 views
1

我想創建約10個XML HTTP請求,如下所示。我想使用i作爲第一個「子女」參考的值,但如果i在執行回調之前發生變化,則i的值與「結果」選項卡中的網址不匹配。我怎麼概括這個?javascript回調函數的泛化

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; 
}); 
+0

這是Javascript中常見的範圍界定問題。它通常是通過引入一個新的範圍層來解決的,那麼你的實際代碼是否實現了一個循環而不是重複調用'xhr()'?另外,您的最終目標是鏈接請求還是並行執行所有請求? –

+0

我是否依賴於哪個訂單發送請求或訂單完成? – EricG

+0

'i'不在回調中使用,只能在立即發生的'.url'分配中使用。所以我沒有看到你的異步行爲。 – Yoshi

回答

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` 
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++; 

}); 
+0

但取決於'完成'的順序,這可能會搞砸了。其實問題是,這是關於訂單「完成」還是訂單「發送」(我假設發送) – EricG

+0

我剛剛注意到那個抱歉!我再也看不到你在哪裏使用,所以也許你可以進一步解釋它如何不匹配「結果選項卡中的網址」? –

+0

暫停一分鐘......我實際上看不出爲什麼你需要一個變量。你不能只是硬編碼的值? –

1

一般來說,你可以做兩件事;

  1. 使用額外的功能
  2. 使用一個額外的變量

在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; 
}); 
+0

你能解釋一下這有助於嗎?我認爲這不是一個範圍問題,而是一個異步調用的問題。 –

+1

當您創建參數對象時,額外的函數將以'i'作爲參數被調用,並且該函數將立即返回該值,即使在創建對象後i的值發生更改時也是如此。 – EricG

+0

正確的問題,是的,這是有道理的! –

-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 
}); 

這給你一個機會讓事情孤立&遏制。