承诺中未正确调用异步Javascript函数

承诺中未正确调用异步Javascript函数,javascript,asynchronous,Javascript,Asynchronous,我有以下代码: //this 'hitches' the scope to the appropriate callback method var hitchWidgetToPopulateHierarchyDefinitionFields = DojoBaseLang.hitch(this, populateHierarchyDefinitionFieldsFromSelectedHierarchyTable); hitchWidgetToPopulateHierarchyDefinition

我有以下代码:

//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);
        }
    );
}
请注意,对象确实已被记录,错误被捕获在catch中

我的目的只是从SelectValuesByField从HierarchyTable返回的值调用addHierarchyLevelSelectionToDOM。问题在于,调用addHierarchyLevelSelectionToDOMvalue时,该值未定义,但console.logvalue调用会打印正确的返回值。然后,我尝试了多个同样有用的承诺:

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);
});
当然,在这种情况下,由于resolve addHierarchyLevelSelectionToDOMvalue失败,因此不会调用第二个console.logvalue。如果可能的话,我想用纯Javascript实现这个目标


非常感谢您的帮助

至少在您的第一个已删除问题中,您可能在Promise构造函数中有错误,更准确地说是在selectValuesByFieldFromHierarchyTable中有错误

只要做:

var p1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve("bla");
  }, 2000);
});
p1.then(function(value) {
  console.log(value);
});
突然间,它起了作用。这就是为什么在大多数情况下还应该有一个reject函数的原因,因为reject不仅在手动拒绝时被调用,而且在抛出错误时也会被调用——无论出于何种原因:

p1.then(
  function resolve(value) {
      console.log(value);
  },
  function reject(error) {
      console.error(error);
  }
);
但是等等!现在,如果您在resolve中有错误,它也会自动失败。因此,使用这种模式更好:

p1.then(
  function resolve(value) {
      console.log(value);
  }
).catch(
  function reject(error) {
      console.error(error);
  }
);
用这个再试一次,画面会变得更清晰

请注意,函数命名不是强制性的,但有助于调试

编辑:关于纯Javascript。你什么意思?这是纯Javascript,承诺也是一种标准。大多数现代浏览器都可以在本机上实现这一点,而对于其他浏览器,只需使用一个应能完美工作的polyfill即可,因为承诺可以100%模拟出来。

试试以下方法:

var p1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn.innerHTML))
  }, 2000);
});
p1.then(addHierarchyLevelSelectionToDOM);

代码的问题在selectValuesByFieldFromHierarchyTable中

里面是对类型为的异步函数的调用

解决方案是返回延迟异步类型,然后返回所需的数据数组uniqueHierarchyLevels


你以前问过这个问题,但我还没来得及写答案就把它删掉了。你想知道为什么这不起作用吗?也许你应该把你的原始代码贴在那里,因为那里更清楚什么地方出了问题。您现在所做的一切只会使它变得更加复杂问题是,调用addHierarchyLevelSelectionToDOMvalue时,该值未定义,但console.logvalue调用会打印正确的返回值。-那是不可能的。请发布一个,包括来自HierarchyTable的SelectValuesByField、SelectedHierarchyDefinition列和addHierarchyLevelSelectionToDOMSo的代码,因为我说过您的错误在别处。在本例中,在addHierarchyLevelSelectionToDOMvalue的调用中,值只是未定义,导致您现在刚刚捕获的错误。这种情况的原因尚不清楚,但我也看到selectedHierarchyDefinitionColumn似乎没有在任何地方定义。或者从HierarchyTable中选择ValuesByField只返回undefined。所以我想你应该先调试这个函数。但同样,如果没有完整的代码,很难说。至少这证明了我的答案是正确的,这与您的实际承诺无关。再次,我非常确定您的问题是由于代码中的某个bug造成的。似乎是TypeError:无法从此行读取未定义代码的属性“length”:对于var i=0;iNote对后来者说:这个答案并不错误,但是我在promise调用中处理异步函数的方式不正确,所以他们提前调用promises,并且在上面的解决方案中出现了错误
var p1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn.innerHTML))
  }, 2000);
});
p1.then(addHierarchyLevelSelectionToDOM);
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);
            })
       });
}