![](/img/trans.png)
[英]Recursion with Asynchronous Functions and Bluebird Promises in JavaScript
[英]Asynchronous Javascript functions not called correctly in promises
我有以下代碼:
//this 'hitches' the scope to the appropriate callback method
var hitchWidgetToPopulateHierarchyDefinitionFields = DojoBaseLang.hitch(this, populateHierarchyDefinitionFieldsFromSelectedHierarchyTable);
hitchWidgetToPopulateHierarchyDefinitionFields();
function selectValuesByFieldFromHierarchyTable(currentlySelectedColumn) {
//query database and return an array of strings
}
function addHierarchyLevelSelectionToDOM (hierarchyLevelsArray) {
var temporaryDataStore= [];
for (var i=0; i<hierarchyLevelsArray.length;i++){
//DO STUFF
}
}
function populateHierarchyDefinitionFieldsFromSelectedHierarchyTable(){
var selectedHierarchyDefinitionColumn = "COLUMN_NAME"
var p1 = new Promise(function( resolve, reject) {
setTimeout(function() {
resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn))
},2000);
});
p1.then(
function resolve(value) {
console.log(value);
addHierarchyLevelSelectionToDOM(value);
}
).catch(
function reject(error) {
console.error(error);
}
);
}
這導致控制台輸出記錄該值,但是在addHierarchyLevelSelectionToDOM
內仍未定義該值:
TypeError: Cannot read property 'length' of undefined
Object {Relevant data }
請注意,該對象確實已記錄,並且錯誤被捕獲在catch中。
我的目的是簡單地調用addHierarchyLevelSelectionToDOM
從返回的值selectValuesByFieldFromHierarchyTable
。 問題在於,當addHierarchyLevelSelectionToDOM(value)
時,該值是不確定的,但是console.log(value)
調用會打印正確的返回值。 然后,我嘗試了對相同結果的多個承諾:
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn))
}, 2000);
});
var p2 = p1.then(function(value) {
console.log(value);
return new Promise(addHierarchyLevelSelectionToDOM(value));
});
p2.then(function(value) {
console.log(value);
});
當然,在這種情況下,由於解決addHierarchyLevelSelectionToDOM(value)
失敗,因此不會調用第二個console.log(value)
。 如果可能的話,我想用純Javascript實現這個目標。
非常感謝您的協助!
至少在您的第一個-已刪除-問題中,您可能在Promise構造函數中出現了錯誤,更確切地說是在selectValuesByFieldFromHierarchyTable
做就是了:
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("bla");
}, 2000);
});
p1.then(function(value) {
console.log(value);
});
突然間它起作用了。 因此,這就是為什么在大多數情況下還應該具有拒絕功能的原因,因為不僅由於手動拒絕,而且當引發錯誤時, 也會由於任何原因調用reject():
p1.then(
function resolve(value) {
console.log(value);
},
function reject(error) {
console.error(error);
}
);
可是等等! 現在,如果您在“解決”中遇到錯誤,它也將無聲地失敗。 因此使用這種模式更好:
p1.then(
function resolve(value) {
console.log(value);
}
).catch(
function reject(error) {
console.error(error);
}
);
再試一次,圖片應該會更清晰。
(請注意,函數命名不是強制性的,但有助於調試)
編輯:關於“純Javascript”。 好吧,你是什么意思? 那是純Javascript,Promises也是一個標准。 大多數現代瀏覽器都可以本機執行此操作,而對於其余的瀏覽器,只需使用應該可以完美工作的polyfill,因為Promises可以100%被“模擬”。
嘗試這個:
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn.innerHTML))
}, 2000);
});
p1.then(addHierarchyLevelSelectionToDOM);
代碼的問題是在selectValuesByFieldFromHierarchyTable
內部
它的內部是對異步函數query的調用Deferred類型的功能
解決方案是返回延遲(異步)類型,然后返回所需的數據數組uniqueHierarchyLevels
function selectValuesByFieldFromHierarchyTable(currentlySelectedColumn) {
//query database and return an array of strings
//now returning the deferred type returned by queryFeatures as well as the array
return hierarchyTableFeatureLayer.queryFeatures(hierarchyTableQuery, function(featureSet){
for (var i = 0; i<featureSet.features.length; i++){
uniqueHierarchyLevels.push(featureSet.features[i])
}
}).then(function afterQuery(){
return uniqueHierarchyLevels;
});
}
function populateHierarchyDefinitionFieldsFromSelectedHierarchyTable(){
var selectedHierarchyDefinitionColumn = "COLUMN_NAME";
deferred.resolve(selectUniqueValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn));
deferred.then(function queryFeaturesAsyncCall(featureSetCallback) {
featureSetCallback.then(
function (hierarchyLevelsArray) {
addHierarchyLevelSelectionToDOM(hierarchyLevelsArray);
},
function (err) {
// Do something when the process errors out
console.log(err);
})
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.