DEV Community

Alex Adamov
Alex Adamov

Posted on

Getting comfortable with promises in JavaScript

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
*/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
})
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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')
  }
})
Enter fullscreen mode Exit fullscreen mode

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)