Having trouble making jQuery buttons selector wait for an AJAX call to finish when executing a PHP exec command? Learn

I am facing a challenge with my php page that contains multiple forms sending an exec command to the server:

Form 0, when the RunAll button is clicked -> it should execute all subsequent button commands sequentially using a jQuery class selector loop

Form 1, Button 1 -> Executes Apache shell cmd 1

Form 2, Button 2 -> Executes Apache shell cmd 2

Form3, Button 3 -> Executes Apache shell cmd 3

The goal is for the RunAll button to trigger all requests asynchronously in ajax mode to prevent the page from freezing, while making sure they are executed one after the other. However, the current issue is that the jQuery loop clicks all buttons simultaneously without waiting for each ajax call to finish before moving on to the next.

I have attempted various methods including: 1- Using a global variable in ajax success 2- Utilizing Promises 3- Implementing Async-await

One of the challenges faced is that due to all processes running at the same time, Apache memory gets exhausted.

 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 );   
            //(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();
                                      } 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);
      }
  }

Answer №1

From what I can see, it appears that your solution is built on a misconception regarding how the await keyword functions in pausing the execution of an async function. The critical point to understand is that only the execution of the async function itself is halted, not the rest of your script's execution, including the function calling the async functions. Refer to MDN on await for more clarity, especially this emphasized paragraph:

An await can split execution flow, allowing the caller of the await's function to resume execution before the deferred continuation of the await's 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.

You are presently invoking your async functions synchronously within your event handler for .btn-info, resulting in the following sequence of execution:

  • asyncClick starts for the initial button ("A1"), and pauses as it awaits the result of doAjax ("D1")
  • asyncClick begins for the second button ("A2"), but halts while waiting for the outcome of doAjax ("D2")
  • (other asyncClick calls are similarly processed)
  • (some time passes)
  • once D1 yields results, A1 resumes execution
  • and so forth...

This concurrent processing behavior is what leads your server to handle everything simultaneously.

You should adjust your logic to trigger the next async call only after the previous one has concluded. There are numerous methods to achieve this, using async/await or regular Promise objects.

Additional points to consider:

  • Inserting console.log() statements in your code allows you to monitor the order of function executions. Focus on tracking when functions are entered and when execution proceeds post an await statement.
  • The concept you're likely seeking is serialization (referring to waiting for a command to finish before moving to the next), which can lead you to valuable resources upon further research.

Regarding this statement:

The Apache runs out of memory because of all processes are running at the same time

It hints at a potential architectural issue since there isn't a semantic necessity to run these commands sequentially; it's merely a constraint from implementation or hardware limitations forcing this approach. Essentially, CMD2 doesn't rely on CMD1 completion for it to make sense; it's just that low memory prevents both from running concurrently

Ideally, your application frontend shouldn't be concerned with these issues and should simply wait for each command's return from the server. It's up to the server's capability to decide whether to process commands concurrently or not.

If you wish to delve deeper into higher-level questions about code organization, platforms like softwareengineering or codereview would be better suited for such discussions.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

javascript extract data from JSON

How can I extract values from the [object Object] in javascript? I have a JSON response from PHP that I am passing into JavaScript. I want to retrieve the GPSPoint_lat and GPSPoint_lon values. var jArray = ; var obj = JSON.parse(jArray); I am gett ...

The issue I am facing is that when I click on a checkbox, only one of them seems to respond

When I click the button, only the first checkbox event is being checked while the rest of them are not. Can someone please provide some guidance on how to fix this issue? $("#cascadeChange").click(function() { //alert("Clicked"); ...

Error message in Angular about undefined JavaScript function

Struggling to make my Angular 17 project functional with Bootstrap (5) and the datePicker feature. Despite following tutorials, I keep encountering a "ReferenceError: datePicker is not defined" error during the app build process. Here are the steps I&apos ...

Retrieve the array from MongoDB based on a specific property

The data stored in my MongoDB collection is structured as follows: [ { "_id": "1", "name": "X", "age": "2", "createdAt": "2020-02-29T22:22:49.491Z", "updatedAt": "2020-02-29T22:22:49.491Z", "__v": 0 ...

Struggling with defining the parameters for the numerical input range from the user

Currently working on a program and encountering an issue with the function below. My main concern is setting limitations for user inputs in the first loop to be between 1 and 69, and between 1 and 26 for the second loop. I initially considered using a do/ ...

Employing setTimeout within a repetitive sequence

function displayColors() { $.each(colors, function(index) { setTimeout(function(){ revealColor(colors[index]); }, 1000); }); } I'm attempting to create a loop where the revealColor function is executed every second until all colors ...

Dynamically validate AngularJS forms with JSON Schema

I am currently trying to dynamically validate JSON in AngularJS. Unfortunately, I have encountered an issue with loading fields from the schema onto the page. My understanding of AngularJS is limited as I am still new to it. Although I have managed to cr ...

Issue with Laravel Jetstream + Inertia: Flash message not showing up after redirecting to the same page

I'm currently facing a problem with displaying flash messages in my Laravel Jetstream application using Inertia.js. Below is the relevant code snippet: In AppLayout.vue <script setup> import { usePage } from "@inertiajs/vue3"; import F ...

Using Titanium for Android to Display High-Quality Images

My goal is to showcase a high-resolution image (minimum size of 2000x2000) on an Android device using Titanium, allowing users to scroll around it similar to a scroll view on iOS. However, I am aware that Android does not offer the same type of scroll view ...

Using HTML and JavaScript, we can set two different color values - one for the background and one for the h1 title

I am trying to save two values, one for the h1 tag and one for the body background. I want the user to select color 1 and color 2. When I press the third button, all changes should be applied and the colors should change. I have attempted this but with no ...

Issue with date range filter functionality not functioning as expected

Struggling to get the date range filter to function properly. Selecting a date triggers it, but nothing is being added to the var filter. I've spent hours trying to solve this issue with no progress. html <div class="form-group"> <input ...

Elementary JavaScript: The Power of HTML Buttons

I'm attempting to create a button that will submit text input, and then display that input as an alert. Here is the current state of my code (which results in an alert displaying "undefined"): <p class="text-right"> <input id="input" type=" ...

Building a React Router powered Backend API

Within my application, I have an Express backend that serves a Login page to users as part of a React App. The app includes a button that guides users through Google's O-Auth process, returning user information in the following manner: router.get("/g ...

Simple JavaScript validation for inputting names

Hey there, I'm a beginner in javascript and I am struggling with a simple input validation using else if statements. Every time I run the code, it goes directly to the else condition. Can someone please assist me? <!DOCTYPE html> <html lang=& ...

Building a JavaScript application with Node.js and MySQL to seamlessly interact with both offline and online databases

As I develop a JavaScript web-app, my plan is to utilize Node.js for connecting the app with an existing MySQL database. My initial question pertains to the structure of the Node code: should it be written in the same .js file as my application or kept se ...

The tale of the Vue Composition API and the mysterious router that vanished into thin air

When attempting to display a component using storybook (vue-cli conf) with the vue-composition-api, an error is encountered: Error: Cannot read property '_router' of undefined The code from file.stories.ts is as follows: import Vue from 'v ...

"Simply tap on an element that has been dynamically inserted into the

Many individuals are familiar with how to attach a "click" event to an element that is dynamically added using the following syntax: $('#main').on('click','.link',function(){ //some code here }); In this example, .link repr ...

Cross-domain scripting with JavaScript

I currently manage 2 subdomains securityservices.example.com workstations.example.com All workstations are associated with the workstations.example.com One of the workstations, known as WS789012 on the domain, is fully qualified as: WS789012.workst ...

The useStarRating() hook continues to display 0 even after the user has interacted with the star component

I've created a custom useStarRating hook to manage the state of a star rating component in my React project. Everything seems to be working properly, but I'm facing an issue with retrieving the updated value of currentValue after the user interac ...

Is it possible to replace JavaScript files that are included in my index page if I am utilizing conditional comments specifically for IE9?

My website works perfectly in all browsers, except for IE9. After some investigation, I discovered that the issue lies with a jQuery plugin called multilevelpush.js. While it works great on other browsers, it simply won't cooperate with IE9. Upon fur ...