larryq
larryq

Reputation: 16299

Await-ing a javascript event handler

I'm struggling with an event handler in javascript, I'm trying to make things respond correctly with async / await.

The issue in the code below is with the file.on event-- I'm struggling to promisify it correctly. Currently the checkSomething method returns before the file.on handler is finished, and so returnValue is always false.

I could use some advice and best practices.

What's a good way to go ensure returnValue is checked / set in the handler before the value is returned? I've tried putting the await keyword in front of the event handler, and in its callback function but that didn't work, and I'm basically scruffing along at this point and could use some tips. Thanks.

const axios = require('axios')
const fs = require('fs')

/*....*/

let isItChecked = await checkSomething()

async function checkSomething() {
    let returnValue = false
    const response = await axios.get('https://someUrl.com', {
        responseType: 'stream'
    })

    const file = fs.createWriteStream('./localFile.txt')

    response.data.pipe(file)

    file.on('finish' () => {
        performATask().then((result) => {
            if (result == 'good') {
                returnValue = true  //need to make sure this is evaluated before returning
            }
        })
    })

    return returnValue
}

Upvotes: 0

Views: 140

Answers (2)

traktor
traktor

Reputation: 19301

Since the event is only used as a signal for processing to continue, you can promisify and await its receipt before continuing with in-line style code. This also means that result need not be declared in outer scope of a nested fumction (which didn't work anyway due to being set asynchronously):

async function checkSomething() {
    const response = await axios.get('https://someUrl.com', {
        responseType: 'stream'
    });

    const file = fs.createWriteStream('./localFile.txt');
    response.data.pipe(file);
    await new Promise( resolve=> file.on(`finish`, resolve)); // wait here

    const result = await  performATask();
    return result == 'good`;
}

Upvotes: 3

junvar
junvar

Reputation: 11574

You're close, you just have to return a promise, which resolves after the execution reaches your desired point (where you have the comment).

Other things to keep in mind:

  • Ensure you only use await from within async functions
  • Use === instead of ==
  • End statements with ;s
const axios = require('axios');
const fs = require('fs');

/*....*/

let isItChecked = await checkSomething();

async function checkSomething() {
  const response = await axios.get('https://someUrl.com', {responseType: 'stream'});

  const file = fs.createWriteStream('./localFile.txt');

  response.data.pipe(file);

  return new Promise(resolve =>
      file.on('finish', () =>
          performATask().then(result => resolve(result === 'good'))));
}

Upvotes: 1

Related Questions