2017-10-17 126 views
0
oModel.create("/SurveySet", oEntry, { 
    success: function(oData) { 
     for (var i = 0; i < questionData.questions.length; i++) { 
      var oEntry = {}; 
      oEntry.SurveyId = oData.SurveyId; 

      oModel.create("/QuestionSet", oEntry, { 
       changeSetId: i.toString(), 
       success: function(oData) { 
        //Additional Processing 

       } 
      } 
     } 
    } 
} 

我正在創建一個SurveySet,它返回一個SurveyId。SAPUI5處理循環的承諾

對於每個調查,我需要在FOR循環中創建一個QuestionSet,每次返回數據以進行其他處理。

問題出在執行的順序。 for循環在從第一次迭代中檢索oData之前遞增。

E.g.如果for循環有0和1,則只執行最後一個元素1。

如何延遲for循環的增量,直到循環的第一次迭代返回oData之後?

+1

:「例如,如果for循環具有0和1,則只執行最後一個元素1。「 ?什麼是確切的問題,你能否詳細說明一下? –

回答

1

您可以將調查數據推到一個數組,然後做FOR循環

var data = []; 

oModel.create("/SurveySet", oEntry, { 
     success: function(oData) { 
     data.push(oData.SurveyId); 
     } 
} 

$.each(data, function(index, value) { 

     for (var i = 0; i < questionData.questions.length; i++) { 
      var oEntry = {}; 
      oEntry.SurveyId = value.SurveyId; 

      oModel.create("/QuestionSet", oEntry, { 
       changeSetId: i.toString(), 
       success: function(oData) { 
        //Additional Processing 

       } 
      } 
     } 

)}; 
2

我猜你在「其他處理」訪問oEntryi

問題是,帶有附加處理的內部成功函數捕獲在外部定義的局部變量,如ioEntry在閉包中。變量值不會被複制。

  1. for循環增量i,改變oEntry並執行oModel.create()方法。
  2. 下一個循環:for循環再次增加i,更改oEntry並再次執行oModel.create()
  3. 當完成循環或任何時候在後端請求完成後,您的內部成功處理程序將被調用。他們訪問只存活了很長時間的外部變量,因爲它們在關閉中被捕獲。而且他們將處於for循環結束時的狀態。

所以,如果您不介意額外的處理可能發生不按順序,您可以將for循環內的代碼移動到單獨的函數中。當你調用從for循環的變量值將被複制的功能,使每個之前提到的關閉將捕捉其不會被用於循環改變的副本:

createSurvey: function(oEntry){ 
    var that = this; 
    oModel.create("/SurveySet", oEntry, { 
     success: function(oData) { 
      for (var i = 0; i < questionData.questions.length; i++) { 
       that.createQuestion(oModel, questionData.questions, i, oData); 
      } 
     } 
    } 
} 
createQuestion(oModel, questions, i, survey){ 
      var oEntry = {}; 
      oEntry.SurveyId = survey.SurveyId; 

      oModel.create("/QuestionSet", oEntry, { 
       changeSetId: i.toString(), 
       success: function(oData) { 
        //Additional Processing 

       } 
      } 

} 

PS:您還可以使用questionData.questions.forEach(function(question, i){ ... });來得到相同的效果。這次匿名函數複製這些值。


如果你需要保持嚴格的順序爲您額外的處理和sequencially發送請求到後端,我的確會建議使用承諾:你說的這個意思

createSurvey: function(oEntry){ 
    var that = this; 
    oModel.create("/SurveySet", oEntry, { 
     success: function(oData) { 
      var promise = Promise.resolve(); 
      questionData.questions.forEach(function(question, i) { //copy local variables 
       //Chain the promises 
       promise = promise.then(function(){ return that.createQuestion(oModel, question, i, oData)}); 
      }); 
      promise.then(function(){ 
       //All done 
      }) 
      .catch(function(){ 
       //Error somewhere. remaining not executed 
      }) 
     } 
    } 
} 
createQuestion(oModel, question, i, survey){ //returns a Promise now 
    var oEntry = {}; 
    oEntry.SurveyId = survey.SurveyId; 

    return new Promise(function(resolve,reject){ //Wrap the UI5 stuff into a Promise 
     oModel.create("/QuestionSet", oEntry, { 
      changeSetId: i.toString(), 
      success: function(oData) { 
       //Additional Processing 
       resolve(oData); 
      }, 
      error: reject 
     } 
    }); 
}