【问题标题】:Using dojo/Deferred with asychronous functions and queries将 dojo/Deferred 与异步函数和查询一起使用
【发布时间】:2020-04-04 18:37:57
【问题描述】:

我无法让某些查询和函数以正确的顺序运行。假设我有 2 个函数可以创建 2 个下拉菜单(dropdown_adropdown_b)。在create_b(items) 之前,必须首先调用create_a(items)。事实上,create_a(items) 创建了dropdown_a,然后包含一个触发function_b(items)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);
        ...
    }
});

现在我想基于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);     

问题是,此时,dom 中可能/可能不存在dijit.byId('projectSelect').set 可能/可能不是函数等...看来如果我像上面那样慢慢运行它在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)

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

【问题讨论】:

    标签: javascript asynchronous promise callback dojo


    【解决方案1】:

    为避免重新构建整个事物,您可以尝试使用 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 回调中移动对 queryTask_b.execute 的调用,并在 create_a 语句之后,该语句尊重您上面的 1、2、3、4 顺序。

    【讨论】:

    • 我将其标记为正确,因为我结合了你们中的两个建议。基本上我使用了ready(function(){} 部分,但我不得不将它一分为二。我将project select 的第一部分应用于create_a 函数,将subproject_select 的第二部分应用于create_b` 函数。我还添加了一个预先检查 id 的部分。查询按顺序运行,函数按顺序运行。然后下拉列表会相应地填充。
    猜你喜欢
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多