簡體   English   中英

JavaScript Promise 回調在 Promise 本身之前執行

[英]The JavaScript Promise callback is executed before the Promise itself

目前我正在處理一個 Oracle APEX 頁面,其中包含用於放置文檔參數的表單。 我的目標是完善機制,根據數據庫中的某些信息定義表單的哪些字段可供用戶使用,哪些字段不可用。

我制作了 PL/SQL 過程並編寫了 JavaScript 函數(以及 AJAX 進程)來幫助我解決這個任務,但是當我需要執行一些 Z686155AF75A60A0F6E9D80C1 后的可用字段時我遇到了問題編輯例如,有時應刷新與表單綁定的某些報表或應從 HTML 頁面中刪除某些輔助元素)。 換句話說,我有function enableFields (在參數頁面加載時執行),它必須執行enableFieldsBase ,然后在輸入參數中定義回調function callbackFunc ,但經過一些測試我發現后者在前者之前執行盡管使用了 JavaScript 承諾。

這是 JavaScript function 使用數據庫中的信息使表單字段可用(或不可用):

function enableFieldsBase(){
    var page = 'P' + $v('pFlowStepId') + '_'; //define the page
    var docID = $v(page + 'DOC_ID'); //define the document

    //get the information which fields are available and which are not
    $.post('wwv_flow.show', 
      {'p_request'      : 'APPLICATION_PROCESS=DOC_ENABLE_FIELDS',
       'p_flow_id'      : $v('pFlowId'),
       'p_flow_step_id' : $v('pFlowStepId'),
       'p_instance'     : $v('pInstance'),
       'x01'            : docID},
    function(pData) {
      var res = eval('(' + pData+ ')');
      if (res.status == "OK") {
        //get the array of objects containing the shortened element names and the availability sign
        var props = res.data;
        //open or close the elements for edit
        for (var i = 0; i < props.length; i++){
          if (props[i].enabled == 1) apex.item(page + props[i].prop).enable();
          else apex.item(page + props[i].prop).disable();
        }
      } else {
         //…the code for catching the exceptions…
      }
    });
}

而這就是JavaScript function,它不僅執行了前一個,還考慮到了回調function:

function enableFields(callbackFunc){
  var page = 'P' + $v('pFlowStepId') + '_';
    
  //check if the variable callbackFunc is really a function
  if (callbackFunc != undefined && typeof(callbackFunc) != 'function'){
    //…the code for catching the exceptions…
  }
    
  if (callbackFunc != undefined){
    var promise1 = new Promise(function(resolve,reject){
      enableFieldsBase();
      return resolve(true);
    });
    $.when(promise1).done(function(){
      callbackFunc();
    });
  } else {
    enableFieldsBase();
  }
}

所以,我的問題如下:我做錯了什么? 是否可以將回調 function 顯式放入enableFieldsBase的代碼中?

我使用 Oracle 11g 和 Oracle APEX 4.2.6.00.03。

問題是您同步調用resolve ,而無需等待發布請求完成。 所以 promise 立即解決。

相反,您應該使用$.post開箱即用返回的 promise:

function enableFieldsBase(){
    var page = 'P' + $v('pFlowStepId') + '_'; //define the page
    var docID = $v(page + 'DOC_ID'); //define the document

    //make sure to RETURN the result of the `$.post` call, and chain a `then` method call
    return $.post('wwv_flow.show', 
      {'p_request'      : 'APPLICATION_PROCESS=DOC_ENABLE_FIELDS',
       'p_flow_id'      : $v('pFlowId'),
       'p_flow_step_id' : $v('pFlowStepId'),
       'p_instance'     : $v('pInstance'),
       'x01'            : docID}).then(function(pData) { // Use the `then` method
      var res = eval('(' + pData+ ')');
      if (res.status == "OK") {
        //get the array of objects containing the shortened element names and the availability sign
        var props = res.data;
        //open or close the elements for edit
        for (var i = 0; i < props.length; i++){
          if (props[i].enabled == 1) apex.item(page + props[i].prop).enable();
          else apex.item(page + props[i].prop).disable();
        }
      } else {
         //…the code for catching the exceptions…
      }
    });
}

在調用代碼中:

if (callbackFunc != undefined){
    enableFieldsBase().then(callbackFunc);
} else {
    enableFieldsBase();
}

正如 jonrsharpe 在下面的評論中指出的那樣,如果您傳遞給then一個不可調用的參數(如undefined ),就好像您根本沒有傳遞回調。 因此,您可以進一步簡化為:

enableFieldsBase().then(callbackFunc);

最好將callbackFunc參數放到enableFields中,然后返回 promise。 然后enableFields的調用者應該自己決定是否要鏈接then調用它(或使用await )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM