2015-09-04 110 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); 
}