Consider such a senario:
function func_topmost(){
...
func_layer1();
pseudo_code for some actions here; // an action that needs to run AFTER the promise in func_layer2 fulfilled.
}
function func_layer1(){
...
func_layer2();
}
function func_layer2(){
var the_vital_promise = $.post('very_slow_backend_response', data);
return the_vital_promise;
}
The above is just an illustration. In reality the call stack could be even deeper and there is always a possibility that another layer of function will be introduced to the call stacks in future development.
My question is, what is the best practice to make sure that the actions in the topmost layer function that dependent on the fulfillment of the promise in the bottom layer attached properly?
Right now I can think of making all the functions in the calling chain async function
all the way to the bottom. I am not sure if this is the right solution, and it makes later maintenance very rigid.
So you have multiple normal functions calling each other, and all of a sudden the one on top of a stack happens to handle some asynchronous task and you are looking for a way to solve the issue with minimum code change. There are 3 ways that I am aware of to handle that and 2 of them are already mentioned, but I think they have some drawbacks.
1. Returning a promise
2. Async/await
async function func_topmost(){
const data = await func_layer1();
pseudo_code for some actions here; // an action that needs to run AFTER the promise in func_layer2 fulfilled.
}
function func_layer1(){
const promise = func_layer2();
return promise;
}
function func_layer2(){
var the_vital_promise = $.post('very_slow_backend_response', data);
return the_vital_promise;
}
3. Dispatch an event
This seems to be the best way of handling the problem to me if you have many functions stacked. You can use events library if you are on Node, or custom DOM events if the environment is the browser. This way you only need to change the first and the last function (if the functions in between doesn't depend on promise completion) and the code structure is kept.
function func_layer2(){
var the_vital_promise = $.post('very_slow_backend_response', data)
.then(res => {
events.emit('customEvent');
});
return the_vital_promise;
}
function func_topmost(){
...
events.on('customEvent', () => {
pseudo_code for some actions here; // an action that needs to run AFTER the promise in func_layer2 fulfilled.
});
func_layer1();
}