承诺中未正确调用异步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);
})
});
}