Promises are difficult to understand for people coming from Python.
I am currently building an application that will have users upload a CSV file containing a list of emails of members of an online community. I used a popular library, Papa parse, to parse the CSV data.
However, I got stuck for a couple of hours.
While I could read the file and output it in the console, I could not assign the data to a variable and transfer it to a database. The trick happened in understanding that the library uses asynchronous functions.
Asynchronous functions
These are functions that do not execute completely in the sequence of the code. Instead, they return a promise that will do something. This promise may take time to complete and in JavaScript the rest of the code that is not dependent on it continues to execute.
This means that any value that is returned by a promise can only be accessed after the code in the scope has finished running.
console.log('beginning')
myPromise.then(value => {console.log('Value inside promise:', value)})
console.log('finish')
/* Output logs:
beginning
finish
Value inside promise: myValue
*/
Another pitfall is that you cannot assign 'value' to a variable and hope to use that value in the rest of your code that is in the same scope of execution as the promise declaration.
let globalVariable
myPromise.then(value => {
globalVariable = value
})
useValue(globalVariable) // incorrect: does not work
This is because the function useValue is being executed before value is returned by myPromise and assigned to globalVariable.
How to handle promises
You basically have to wait for the promise to execute. Include the code that uses the result of the promise inside the .then syntax.
myPromise.then(value => {
useValue(value) // works! waits for value
})
You can also use an async function with the await keyword.
async function getValue () {
// ...
return value
}
async function main () {
const value = await getValue() // works! waits for value
useValue(value)
}
main()
Or finally, you can assign to a variable but only use the value in code that runs after. For example, code that runs after an event is triggered.
let globalVariable
myPromise.then(value => {
globalVariable = value
})
myButton.addEventListener('click', event => {
if (globalVariable) {
useValue(globalVariable)
// correct but only when click happens after then()
} else {
console.log('globalVariable is not yet available')
}
})
The key lesson is to be careful with async functions and promises and think about the sequence in which your code will run.
Top comments (0)