Javascript esriRequest (dojo)在函数异步问题

Javascript esriRequest (dojo) in a function async issue

本文关键字:函数 异步 问题 esriRequest dojo Javascript      更新时间:2023-09-26

我面临以下同步问题。如果它有一个简单的解决方案/变通方法,我不会感到惊讶。BuildMenu()函数从另一个代码块调用,它调用CreateMenuData(),它向返回一些数据的服务发出请求。问题是,由于在使用数据变量时是对服务的异步调用,因此它是未定义的。我提供了js日志,也显示了我的观点。

        BuildMenu: function () {
            console.log("before call");
            var data=this.CreateMenuData();
            console.log("after call");
            //Doing more stuff with data that fail.
        }

CreateMenuData: function () {
        console.log("func starts");
        data = [];
        dojo.forEach(config.layerlist, function (collection, colindex) {
            var layersRequest = esriRequest({
                url: collection.url,
                handleAs: "json",
            });
            layersRequest.then(
                function (response) {
                    dojo.forEach(response.records, function (value, key) {
                        console.log(key);
                        data.push(key);

                    });
                }, function (error) {
                });
        });
        console.log("func ends");
        return data;
    }
   Console log writes:
   before call
   func starts
   func ends
   after call
   0
   1
   2
   3
   4

仅供参考:不建议使用任何"dojo."。确保您在"require"中拉出所需的所有模块。

Ken给你指出了正确的方向,浏览链接并熟悉异步请求。

然而,我想指出的是,你不只是处理一个异步请求,但潜在的可能有更多的他们,你正试图填补"数据"。为了确保只在所有请求完成时处理结果,您应该使用"dojo/promise/all"。

CreateMenuData: function (callback) {
        console.log("func starts");
        requests = [];
        data = [];
        var scope = this;
        require(["dojo/_base/lang", "dojo/base/array", "dojo/promise/all"], function(lang, array, all){
            array.forEach(config.layerlist, function (collection, colindex) {
                var promise = esriRequest({
                    url: collection.url,
                    handleAs: "json",
                });
                requests.push(promise);
            });
            // Now use the dojo/promise/all object
            all(requests).then(function(responses){
                // Check for all the responses and add whatever you need to the data object.
                ...
                // once it's all done, apply the callback. watch the scope! 
                if (typeof callback == "function")
                    callback.apply(scope, data);
            });
        });        
    }

现在你已经准备好了这个方法,把它命名为

BuildMenu: function () {
    console.log("before call");
    var dataCallback = function(data){
        // do whatever you need to do with the data or call other function that handles them.       
    }
    this.CreateMenuData(dataCallback);  
}