将 dojo/Deferred 与异步函数和查询一起使用
Using dojo/Deferred with asychronous functions and queries
我在以正确的顺序向 运行 获取某些查询和函数时遇到问题。假设我有 2 个创建 2 个下拉菜单的函数(dropdown_a
、dropdown_b
)。依次 create_a(items)
必须在 create_b(items)
之前先被调用。事实上,create_a(items)
创建 dropdown_a
,然后包含触发 function_b(items)
的 on('change')
事件,进而创建 dropdown_b
。要为每个函数获取参数 items
,我首先必须查询一个 REST
服务。如果不粘贴大量代码(它很大),工作流程将如下所示:
function create_a(items):
var projectNode = dom.byId("projectDropdown");
...
var projectSelector = new Select({
name: "projectSelect",
id: "projectSelect",
options: projectsOptions
}).placeAt(projectNode).startup();
dijit.byId('projectSelect').on('change', function (e) {
var subprojectQuery = new esriQuery();
... // creates a query to get subproject items
subprojectAccessQueryTask.execute(subprojectQuery,
function (results) {
let records = results.features;
createSubprojectDropdown(records); // calls the subproject function
},
function (error) {
console.log("query error: ", error);
}
}); // End of deferred Query Task for Project Name
});
}
function create_b(items) {
var subprojectNode = dom.byId("subprojectDropdown");
var p = registry.byId('subprojectSelect');
if (p) {
p.destroyRecursive();
}
var subprojectSelector = new Select({
name: "subprojectSelect",
id: "subprojectSelect",
options: subprojectsOptions
}).placeAt(subprojectNode).startup();
dijit.byId('subprojectSelect').on('change', function (e) {
thisWidget.loadData(e, proj_type_obj);
});
thisWidget.loadData();
}
// Query 1 - Projects
var queryTask_a = new QueryTask();
queryTask_a.execute(query_a_obj,
function (results) {
...
create_a(results);
...
}
});
// Query 2 Subprojects
var queryTask_b = new QueryTask();
queryTask_a.execute(query_a_obj,
function (results) {
...
create_b(results);
...
}
});
现在我想根据 value
触发项目下拉 on('change')
事件。完成后,我想对子项目下拉列表执行相同的操作。像这样:
var info_proj_name = "project_a";
var subproj_name = "subproject_b"
dijit.byId('projectSelect').set("value", info_proj_name);
dijit.byId('subprojectSelect').set("value", subproj_name);
问题是,此时,dijit.byId('projectSelect')
may/may不存在于dom
,.set
may/may不是函数等。 ..似乎如果我 运行 它像上面那样在 Chrome Devtools
中慢慢地工作但是当我让应用程序按原样 运行 时,下拉菜单的时间似乎有滞后由查询以及调用 dijit.byId('projectSelect').set("value", info_proj_name);
时创建和填充。因为我已经在使用 Dojo/Dijit
,所以我正在尝试按顺序将 promise/callback
之类的 Deferred
功能应用到 运行 一切:
1) query a (get list of items for project dropdown)
2) call create_a function (create project dropdown, trigger subproject process)
3) query b (get list of items for subproject dropdown)
4) call create_b function (create subproject dropdown)
5) select an option from projects dropdown (triggers subprojects query and subrprojects dropdown)
6) select and option from subprojects dropdown (triggers subprojects on(change) event)
对于如何应用类似的东西将这些东西链接在一起,我有些困惑。关于如何在一般意义上设置它有什么建议吗?
为避免重新构建整个架构,您可以尝试使用 dojo/ready(请参阅 here 了解文档):
ready(function(){
dijit.byId('projectSelect').set("value", info_proj_name);
ready(function(){
dijit.byId('subprojectSelect').set("value", subproj_name);
});
});
如果不行,下一个可能性是setTimeout:
setTimeout(function(){
dijit.byId('projectSelect').set("value", info_proj_name);
setTimeout(function(){
dijit.byId('subprojectSelect').set("value", subproj_name);
}, timeout1);
}, timeout2);
然后对 timeout1 和 timeout2 进行猜测,如果这些语句需要等到服务器响应,请首先祈祷。
现在重新架构当然会有帮助。我将从 queryTask_a.execute 回调内和 create_a 语句之后移动对 queryTask_b.execute 的调用开始,这符合您上面的 1、2、3、4 顺序。
我在以正确的顺序向 运行 获取某些查询和函数时遇到问题。假设我有 2 个创建 2 个下拉菜单的函数(dropdown_a
、dropdown_b
)。依次 create_a(items)
必须在 create_b(items)
之前先被调用。事实上,create_a(items)
创建 dropdown_a
,然后包含触发 function_b(items)
的 on('change')
事件,进而创建 dropdown_b
。要为每个函数获取参数 items
,我首先必须查询一个 REST
服务。如果不粘贴大量代码(它很大),工作流程将如下所示:
function create_a(items):
var projectNode = dom.byId("projectDropdown");
...
var projectSelector = new Select({
name: "projectSelect",
id: "projectSelect",
options: projectsOptions
}).placeAt(projectNode).startup();
dijit.byId('projectSelect').on('change', function (e) {
var subprojectQuery = new esriQuery();
... // creates a query to get subproject items
subprojectAccessQueryTask.execute(subprojectQuery,
function (results) {
let records = results.features;
createSubprojectDropdown(records); // calls the subproject function
},
function (error) {
console.log("query error: ", error);
}
}); // End of deferred Query Task for Project Name
});
}
function create_b(items) {
var subprojectNode = dom.byId("subprojectDropdown");
var p = registry.byId('subprojectSelect');
if (p) {
p.destroyRecursive();
}
var subprojectSelector = new Select({
name: "subprojectSelect",
id: "subprojectSelect",
options: subprojectsOptions
}).placeAt(subprojectNode).startup();
dijit.byId('subprojectSelect').on('change', function (e) {
thisWidget.loadData(e, proj_type_obj);
});
thisWidget.loadData();
}
// Query 1 - Projects
var queryTask_a = new QueryTask();
queryTask_a.execute(query_a_obj,
function (results) {
...
create_a(results);
...
}
});
// Query 2 Subprojects
var queryTask_b = new QueryTask();
queryTask_a.execute(query_a_obj,
function (results) {
...
create_b(results);
...
}
});
现在我想根据 value
触发项目下拉 on('change')
事件。完成后,我想对子项目下拉列表执行相同的操作。像这样:
var info_proj_name = "project_a";
var subproj_name = "subproject_b"
dijit.byId('projectSelect').set("value", info_proj_name);
dijit.byId('subprojectSelect').set("value", subproj_name);
问题是,此时,dijit.byId('projectSelect')
may/may不存在于dom
,.set
may/may不是函数等。 ..似乎如果我 运行 它像上面那样在 Chrome Devtools
中慢慢地工作但是当我让应用程序按原样 运行 时,下拉菜单的时间似乎有滞后由查询以及调用 dijit.byId('projectSelect').set("value", info_proj_name);
时创建和填充。因为我已经在使用 Dojo/Dijit
,所以我正在尝试按顺序将 promise/callback
之类的 Deferred
功能应用到 运行 一切:
1) query a (get list of items for project dropdown)
2) call create_a function (create project dropdown, trigger subproject process)
3) query b (get list of items for subproject dropdown)
4) call create_b function (create subproject dropdown)
5) select an option from projects dropdown (triggers subprojects query and subrprojects dropdown)
6) select and option from subprojects dropdown (triggers subprojects on(change) event)
对于如何应用类似的东西将这些东西链接在一起,我有些困惑。关于如何在一般意义上设置它有什么建议吗?
为避免重新构建整个架构,您可以尝试使用 dojo/ready(请参阅 here 了解文档):
ready(function(){
dijit.byId('projectSelect').set("value", info_proj_name);
ready(function(){
dijit.byId('subprojectSelect').set("value", subproj_name);
});
});
如果不行,下一个可能性是setTimeout:
setTimeout(function(){
dijit.byId('projectSelect').set("value", info_proj_name);
setTimeout(function(){
dijit.byId('subprojectSelect').set("value", subproj_name);
}, timeout1);
}, timeout2);
然后对 timeout1 和 timeout2 进行猜测,如果这些语句需要等到服务器响应,请首先祈祷。
现在重新架构当然会有帮助。我将从 queryTask_a.execute 回调内和 create_a 语句之后移动对 queryTask_b.execute 的调用开始,这符合您上面的 1、2、3、4 顺序。