簡體   English   中英

在Promise中未正確調用異步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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM