繁体   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