Javascript how to chain promises that include ajax

24 views Asked by At

I'm trying to construct a processing pipeline builder of sorts, where the user can define the order of operations. I need to use the resulting list of operations to determine the sequence in which functions are being chained together. Each internal function contains an $.ajax() call, and I need for that cal to complete before the next processing step begins. The processing steps must proceed synchronously, despite the internal components of each step being asynchronous.

It seems like Promise chaining would do exactly what I need, but I'm failing at adapting the examples on this page to my use case (see below for simplified pseudo-code of what I've tried to do). I can't figure out how to weave waiting for runProcess_() to finish before fulfilling the Promise.

Can anyone help?

var pipe_order = ['C', 'A', 'B']  // this is user-defined, order can change

function runProcessA() {
    var data = { "some_data": some_data }
    $.ajax({
        type: 'POST',
        contentType: 'application/json',
        url: '/run_ProcessA',
        data: data,
        success: (response) => {
            // return message for pipeline functionality
            var pipe_step_response = 'ProcessA Step Complete.'
            return pipe_step_response;
        }
    });
}


////////////////
// FOR SAKE OF SIMPLICITY, assume runProcessB() & runProcessC()
// are mostly identical to runProcessA()
////////////////


function failureCallback(error) {
    console.error(`Error in process step: ${error}`);
}

function runPipeItem(process='end_of_pipe', index=0) {

    index += 1  // increment the index so there is not a 'Step 0'

    return new Promise((resolve) => {
        setTimeout(() => {
          
            if (process!=='end_of_pipe') {
                console.log('Pipeline beginning: Step ' + index);

                if (process==='correct') {
                    console.log('runProcessA: start')
                    var step_complete = runProcessA(process, true);
                } else if (process==='translate') {
                    console.log('runProcessB: start')
                    var step_complete = runProcessB(process, true);
                } else if (process==='summary') {
                    console.log('runProcessC: start')
                    var step_complete = runProcessC(process, true);
                }

                // record that the process is finished
                console.log(step_complete)
                console.log('Pipeline finished: Step ' + index);

                // reveal HTML element
                document.getElementById(`step-${index}-completed`).style.display = "block";

            }

          // The fulfillment value of the promise
          resolve(index);
        }, 200);
      });
}


function runPipeline(pipe_order) {
    var uploadStatus = checkUploadReady();
    if (typeof uploadStatus === "string") {
        alert(uploadStatus);
        return; // Stop the function execution
    } 

    // check status and send stop request if running
    const stopSignal = toggleRunStatus();
    if (stopSignal) {
        return; // Stop the function execution
    }

    // JSON container for anything that needs to be passed to Python function
    var data = {
        "pipe_order": pipe_order,
    }

    // iterating through pipe_order
    runPipeItem(pipe_order[0], 0)  // step 1
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 2
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 3
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 4
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 5
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 6
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 7
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 8
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 9
        .then((newIndex) => runPipeItem(pipe_order[newIndex], newIndex))  // step 10
        .then((newindex) => {
            console.log('Pipeline completed all steps.');
        })
        .catch(failureCallback);

}
0

There are 0 answers