[英]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.