簡體   English   中英

jQuery 按鈕選擇器等待 ajax 完成 php exec 命令使用異步等待不起作用

[英]jQuery buttons selector wait ajax finished php exec command using async-await not working

我有一個 php 頁面,其中有多個 forms 正在向服務器發送 exec 命令:

形式 0,按鈕 RunAll -> 它必須使用 jQuery class 選擇器循環順序運行以下所有按鈕命令

表格 1,按鈕 1 -> 執行 Apache shell cmd 1

表格 2,按鈕 2 -> 執行 Apache shell cmd 2

Form3,按鈕 3 -> 執行 Apache shell cmd 3

我希望 RunAll 按鈕運行 ajax async = true 中的所有請求,以不凍結頁面,而是一個接一個地按順序運行。 問題是 jQuery 循環同時單擊所有按鈕,我無法等待(使用異步等待)第一個 ajax 調用在單擊第二個按鈕之前完成,然后再單擊第三個按鈕。

請幫我。

我在 ajax 中嘗試了 1- 全局變量成功:2- 承諾 3- 異步等待

Apache 用完 memory 因為所有進程同時運行

 function submitMultiForm(){
$('.btn-info').each(function() {
    asyncClick($(this));
});
 }



async function asyncClick(myBttObj)
{
    //GET THE SPECIFIC FORM AND TEXT AREA
    var myForm = myBttObj.parent();//alert(myForm.attr('id'));
    var myFormAreaText = myBttObj.siblings('.myanswer');//alert(myFormAreaText.attr('id'));
    //SET icons
    var mySpinIcon = myBttObj.siblings('.fa-spin');
    var mySuccIcon = myBttObj.siblings('.fa-check');
    var myErrIcon = myBttObj.siblings('.fa-times');
    var myErrAjxIcon = myBttObj.siblings('.fa-exclamation-triangle');

    var url = myForm.attr("action");
    var serializedData = myForm.serialize()+'&'+$('#fparam').serialize();

    try {

        const res = await doAjax(url, serializedData, mySpinIcon, mySuccIcon, myErrIcon,myErrAjxIcon);

            //write always the log
            var myAreaID = myFormAreaText.attr('id');
            //var filtered_data = res.html();
            myFormAreaText.append( res );   //I added exit to the if isset($_POST) to not giving back the whole page
            //(because the url is the same page of the origin of the ajax request)
            //brwsr console
            console.log(myAreaID)+':';
            console.log(res);

            //blur off button
            myBttObj.blur();

    } catch(err) {
        console.log(err);
    }
}


  function doAjax(url, serializedData, mySpinIcon, mySuccIcon, myErrIcon,myErrAjxIcon)
  {
      let result;

      try {
            result = $.ajax({ url:url,
                                  type:"post",
                                  data: serializedData,
                                  datatype: 'html',
                                  beforeSend: function() {mySpinIcon.show();mySuccIcon.hide();myErrIcon.hide();myErrAjxIcon.hide()},
                                  success: function(data) {
                                      if ( data.toLowerCase().indexOf("error") >-1 ) {
                                          mySpinIcon.hide();mySuccIcon.hide();myErrIcon.show();myErrAjxIcon.hide();//error from the shell
                                      } else {
                                          mySpinIcon.hide();mySuccIcon.show();myErrIcon.hide();myErrAjxIcon.hide();
                                      }
                                  },
                                  error: function() {mySpinIcon.hide();mySuccIcon.hide();myErrIcon.hide();myErrAjxIcon.show()}
                              });
          return result;
      } catch (error) {
          console.error(error);
      }
  }

您嘗試的解決方案似乎是基於對await關鍵字如何暫停執行async function 的誤解。 這里的關鍵見解是,只有您的async function 的執行被暫停,而不是您的腳本的 rest 的執行,例如調用 asyncZ 函數的async函數。 請參閱MDN on await以獲得很好的解釋,特別是本段(強調我的):

await 可以拆分執行流程,允許 await 的 function 的調用者在 await 的 function 的延遲繼續之前恢復執行 After the await defers the continuation of its function, if this is the first await executed by the function, immediate execution also continues by returning to the function's caller a pending Promise for the completion of the await's function and resuming execution of that caller .

請注意,您在.btn-info的事件處理程序中同步調用異步函數,從而導致以下執行順序:

  • asyncClick為第一個按鈕(“A1”)運行,它的執行在等待doAjax (“D1”)產生結果時暫停
  • asyncClick為第二個按鈕(“A2”)運行,它的執行在等待doAjax (“D2”)產生結果時暫停
  • (其他asyncClick調用如上執行)
  • (一段時間過去了)
  • 當 D1 產生時,A1 繼續執行
  • 等等...

這就是導致您的服務器開始同時處理所有內容的原因。

相反,您需要顯式添加僅在前一個異步調用返回時觸發下一個異步調用的邏輯。 有很多方法可以做到這一點,使用async/await以及普通的 Promise 對象。

補充說明:

  • 如果你用一些console.log()語句亂扔代碼,你將能夠檢查你的函數的執行順序。 (您感興趣的日志記錄點是輸入函數的時間,以及await語句后繼續執行的時間。)
  • 您似乎正在尋找的關鍵字是序列化(描述在下一個命令之前等待完成),如果您將此術語添加到搜索中,您應該能夠找到好的資源。

在更高級別的注釋中,這句話:

Apache 用完 memory 因為所有進程同時運行

表明您可能遇到架構問題,因為實際上沒有語義需要運行這些序列化的命令,它只是一個基於實現或基於硬件的限制,迫使您這樣做。 (即,在運行 CMD1 之前,並不是說 CMD2 沒有意義,只是由於 memory 較低,您的服務器無法同時運行兩者。)

理想情況下,您的應用程序前端根本不需要知道這些問題,它應該能夠等到服務器返回每個命令——服務器是否能夠同時處理這些命令,取決於服務器的自由裁量權。

然而,這些關於代碼組織的更高級別的問題將更適合網絡的其他站點,例如軟件工程或代碼審查

暫無
暫無

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

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