I am trying to simply chain some async functions together so they operate in order. I am probably making a basic error.
I just want the printFirst to run and then once complete for printSecond to run.
below is my code that does not work
const printFirst = ()=>{
console.log('First')
}
const printSecond = ()=>{
console.log('Second')
}
// Print this first (after 2 sec)
const first = () =>{
setTimeout(printFirst,2000)
}
// Once the above function is run then run this
const second = () =>{
setTimeout(printSecond,2000)
}
first()
.then(second())
I get the error
node timeout.js
file:///Users/bob/Documents/dev/javascript/node/nodeScratch/timeout.js:20
.then(second())
^
TypeError: Cannot read properties of undefined (reading 'then')
at file:///Users/bob/Documents/dev/javascript/node/nodeScratch/timeout.js:20:1
at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
at async loadESM (node:internal/process/esm_loader:88:5)
at async handleMainPromise (node:internal/modules/run_main:61:12)
I did see a post here How do I access previous promise results in a .then() chain? which suggests that I may not have to use "then". HOwever I am not sure if that is actually relavant to my usecase.
CodePudding user response:
Basic async functions in JS are based around Promises. You can write a Promise that waits for a network response or other IO. You can write one that waits for user interaction. You can also write one that waits for the end of a setTimeout
. This is one example of that:
const printFirst = ()=>{
console.log('First')
}
const printSecond = ()=>{
console.log('Second')
}
// Print this first (after 2 sec)
const first = () => new Promise ((resolve, reject) => {
setTimeout(() => resolve(printFirst()), 2000)
})
// Once the above function is run then run this
const second = () =>{
setTimeout(printSecond,2000)
}
first()
.then (second)
As well as wrapping your first function in a new Promise
call, we also need to switch
first () .then (second ())
to
first () .then (second)
The initial one fires the second
function immediately and passes the result of it to .then
. Instead, we want to pass the function itself. For more complex needs, you could do this instead:
first () .then (result => second (result, someOtherArgument))
If you want something else to run after second
, then it also needs to be wrapped in a Promise
.
CodePudding user response:
The first
function needs to be async
so as to return a promise on which you can then call .then()
:
const printFirst = () => {
console.log('First')
}
const printSecond = () => {
console.log('Second')
}
const first = async() => {
setTimeout(printFirst, 2000)
}
const second = () => {
setTimeout(printSecond, 2000)
}
first().then(() => second())