I’m trying to create a routine to sequentially execute a series of test processes. I can’t even figure out how to create a simulation function for a long process. It uses a timer to ensure sequential order (one process doesn’t start until the previous one finishes). I’ve tried many things, here is an example of what seems like it might work…
async function someLongProcess(myInfoStr) {
// Some async process that takes time
console.log(myInfoStr + ": Process Starting");
setTimeout(()=>{
console.log(myInfoStr + ": Process Finishing");
return myInfoStr + ": Process Finished";
}, 1000);
}
someLongProcess("Test A").then(
function(value) { console.log(value) },
function(error) { console.log("Oh oh!: " + error) }
);
The result I wanted: "Test A: Process Starting", "Test A: Process Finishing", "Test A: Process Finished".
The result I got: "Test A: Process Starting", "undefined", "Test A: Process Finishing".
I understand it didn’t work because the return was inside the anonymous function, and someLongProcess didn’t return any promise at all. And of course I already tried to just put the return after the setTimer block which also failed: "Test A: Process Starting", "Test A: Process Finished", "Test A: Process Finishing". I’ve been dorking around with this for hours. Is there a way to do it? TIA
2
Answers
You have to return
Promise
by usingnew Promises()
.That takes two arguments of first for fulfilled and another for rejection obviously we get in our catch block.
And you can’t get
error
inthen
block, it will visible only incatch
block. Below I have addedisError
argument to simulate that andseconds
argument forsetTimeout
More about Promise
MDN’s description for
async
reads:This means, your
someLongProcess()
async function does return a promise.But your problem is (as you have correctly identified): The
return
statement returns from the closest function; in this case, your anonymous callback function forsetTimeout()
.Callback-based functions like
setTimeout()
can be "promisified" by using thePromise
constructor, to have access to theresolve
(andreject
) function of itsexecutor
function.To "promisify", simply call the callback-based function in the
executor
, and resolve it in the callback-based function’s callback:Note: The
async
keyword allows for promises to beawait
ed; thePromise
constructor provides theresolve
andreject
functions. You can declare a function asasync
while also using thePromise
constructor for both benefits; however, in the above exampleasync
is not necessary.Using the above
timeout()
async function (async since it returns a promise) allows for a simplersomeLongProcess()
function.Example with chained promises:
Example with
async
:I was unaware that the
.then()
method accepts a second parameter for aonRejected
callback. I usually see.catch()
in favour of it, but I guess I learned something from your question as well!Make sure to learn about the benefits of both
async
/await
and thePromise
constructor. Since either approaches return promises, both allow for chained promises.For the future: You should also be aware of
Promise.all()
and similar functions, should you want to run multiple async functions in parallel instead of sequentially.