使用dojo /使用异步功能和查询延迟

问题描述 投票:0回答:1

我在使某些查询和函数按正确顺序运行时遇到问题。假设我有2个创建2个下拉菜单的函数(dropdown_adropdown_b)。依次必须先调用create_a(items),然后再调用create_b(items)。实际上,create_a(items)创建dropdown_a,然后包含一个触发on('change')function_b(items)事件,而该事件又会创建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);
        ...
    }
});

现在,我想基于on('change')触发项目下拉列表value事件。完成后,我想对子项目下拉菜单执行相同的操作。像这样:

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')可能/可能不存在,dom可能/可能不存在函数,等等...看来,如果我像上面那样缓慢运行, .set工作正常,但是当我让应用程序按原样运行时,查询创建和填充下拉列表的时间以及调用Chrome Devtools的时间似乎有所滞后。由于我已经在使用dijit.byId('projectSelect').set("value", info_proj_name);,因此我尝试应用Dojo/Dijit之类的promise/callback功能来按顺序运行所有内容:

Deferred

我对如何应用这样的东西将这些东西链接在一起感到困惑。关于如何进行一般设置的任何建议?

javascript asynchronous promise callback dojo
1个回答
1
投票

为了避免重新构建整个结构,您可以尝试使用dojo / ready(有关文档,请参见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) :]

here

如果不起作用,下一个可能性是setTimeout:

ready(function(){
    dijit.byId('projectSelect').set("value", info_proj_name);
    ready(function(){
        dijit.byId('subprojectSelect').set("value", subproj_name); 
    });
});

然后对timeout1和timeout2进行猜测,如果这些语句需要等到服务器响应,则首先要指责。

现在当然,重新架构会有所帮助。首先,将调用移动到queryTask_a.execute回调内的queryTask_b.execute内,并在create_a语句之后进行,该语句遵循上述1、2、3、4的顺序。

© www.soinside.com 2019 - 2024. All rights reserved.