我有一個函式,它本質上創建一個物件,然后將每個新創建的物件推送到一個物件陣列中。但是我面臨一個問題,即只有最后一個正在創建的物件(在我的 for 回圈中)被推送到我的物件陣列中。
我首先宣告我的物件和物件陣列:
this.locationObjectArray = [];
this.locationObject = {};
然后我宣告一個等于“this”的變數“that”,這樣我就可以在回呼中使用上面宣告的物件和物件陣列:
var that = this;
然后我讀取了一個 odata 物體,它回傳一個帶有指定物體資料的成功回呼:
oModel.read("/Customers", {
success: function (resp) {
var promises = [];
for (var x = 0; x < resp.results.length; x ) {
// Set tooltip property
var tooltip = resp.results[x].Country;
that.locationObject.tooltip = tooltip;
// Set type property
that.locationObject.type = "Inactive";
// Set position property
var request = $.ajax({
url: "https://api.opencagedata.com/geocode/v1/json?key=d3e40bf9b50247d4acf8122c543c5187&q=" tooltip,
type: "GET",
dataType: 'json',
success: function (resp) {
that.locationObject.pos = resp.results[0].geometry.lng ";" resp.results[0].geometry.lat ";0";
}
});
// Populate promises and locationObjectArray
that.locationObjectArray.push(that.locationObject);
promises.push(request);
console.log(that.locationObject);
}
$.when.apply(null, promises).done(function(){
// console.log(that.locationObjectArray);
that.getView().getModel("map").setProperty("/Spots", that.locationObjectArray);
})
}
})
我創建了一個名為 Promise 的陣列,因為在我的 for 回圈中我正在向 API 發出 Ajax 請求,該 API 每次回圈時都會回傳一個 Promise。我需要包含每個請求(承諾),以便我可以將函式的其余部分設定為僅在收到每個請求(每個回圈的)中請求的所有資料后才運行。
然后我創建我的 for 回圈。
在 for 回圈中,我開始設定先前宣告的“locationObject”的每個屬性。屬性為:“tooltip”(locationObject.tooltip)、“type”(locationObject.type)和“pos”(locationObject.pos)。“工具提示”和“型別”這兩個屬性都是直截了當的。只有屬性“pos”會導致困難,因為此資料是作為每個回圈中的 promise 成功回呼的結果回傳的。
盡管如此,然后我將新創建的物件推送到物件陣列,并將回圈 promise 推送到 promises 陣列。
一旦 for 回圈完成并解決了所有承諾,我就設定了我的資料模型。
盡管結果物件陣列 (locationObjectArray) 如下所示:
整個陣列被填充(對于每個回圈),其中包含在 locationObject 中為最終回圈收集的資料。
我試圖在每個回圈開始時重置物件(locationObject):
...
for (var x = 0; x < resp.results.length; x ) {
that.locationObject = {};
...
但是,這會干擾 Ajax 請求以獲取每個物件的“pos”屬性資料,并且僅使用“tooltip”和“type”屬性集成功構造了結果陣列:
我不確定我能做些什么來解決這個問題,或者為什么現在忽略承諾,任何建議/建議將不勝感激。
uj5u.com熱心網友回復:
這段代碼有幾個問題。我看到的主要是你只有一個locationObject
你不斷修改并一遍又一遍地推入陣列的。由于.push()
推送對該物件的參考(不制作副本),因此您最終會得到一個包含所有相同物件的陣列,并且它具有您處理的最后一項的值。
您可以通過locationObject
在回圈中創建一個新的來解決該主要問題。以下是我對重寫的建議:
oModel.read("/Customers", {
success: async function(resp) {
for (let result of resp.results) {
const locationObject = {};
const tooltip = result.Country;
locationObject.type = "Inactive";
const geoData = await $.ajax({
url: "https://api.opencagedata.com/geocode/v1/json?key=d3e40bf9b50247d4acf8122c543c5187&q=" tooltip,
type: "GET",
dataType: 'json',
});
locationObject.pos = geoData.results[0].geometry.lng ";" geoData.results[0].geometry.lat ";0";
that.locationObjectArray.push(that.locationObject);
}
that.getView().getModel("map").setProperty("/Spots", that.locationObjectArray);
}
});
這使用回傳的承諾并$.ajax()
擺脫success
. $.ajax()
它還通過序列化for
回圈來簡化代碼await
。
如果您想并行運行所有 ajax 呼叫并避免使用await
,您可以這樣做:
oModel.read("/Customers", {
success: function(resp) {
Promise.all(resp.results.map(result => {
const locationObject = {};
const tooltip = result.Country;
locationObject.type = "Inactive";
return $.ajax({
url: "https://api.opencagedata.com/geocode/v1/json?key=d3e40bf9b50247d4acf8122c543c5187&q=" tooltip,
type: "GET",
dataType: 'json',
}).then(geoData => {
locationObject.pos = geoData.results[0].geometry.lng ";" geoData.results[0].geometry.lat ";0";
return locationObject;
});
})).then((locationArray) => {
that.getView().getModel("map").setProperty("/Spots", locationObjectArray);
});
}
});
請注意,這完全避免了使用that.locationObject
and that.locationObjectArray
。結果在沒有那些更高范圍的變數的情況下在內部收集和使用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/490664.html
標籤:javascript 数组 阿贾克斯 目的 承诺