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