2015-09-04 54 views
0

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

 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 
+0

可能重复[如何返回从异步调用的响应?](http://stackoverflow.com/questions/14220321 /如何对返回的响应从 - 一个异步呼叫) –

回答

0

仅供参考:使用任何东西“dojo”。已弃用。确保您在“需要”中拉出所需的所有模块。

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); 
}