我有以下代码:
//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);
});
当然,在这种情况下,由于解决console.log(value)
失败,第二个addHierarchyLevelSelectionToDOM(value)
不会被调用。如果可能的话,我想用纯Javascript来实现这个目标。
非常感谢任何帮助!
答案 0 :(得分:3)
至少在你的第一个被删除的问题中,很可能你在Promise构造函数中有错误,更准确地说是selectValuesByFieldFromHierarchyTable
只是做:
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("bla");
}, 2000);
});
p1.then(function(value) {
console.log(value);
});
突然间它起作用了。所以这就是为什么在大多数情况下你也应该有一个拒绝函数的原因,因为不仅在你手动拒绝时调用reject(),而且在抛出错误时也 - 无论出于何种原因:< / p>
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,因为Promise可以100%“模拟”。
答案 1 :(得分:1)
试试这个:
User::updating(function ($user) {
$dirty = $user->getDirty();
$original = $user->getOriginal();
});
答案 2 :(得分:0)
代码问题出在selectValuesByFieldFromHierarchyTable
内部是对queryFeatures类型的异步函数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);
})
});
}