1

I'm trying to learn Asynchronous programming with NodeJS and I'm having trouble understanding how to create usable functions.

I'm trying to compare the results of a HTTP get request and a file read all inside an "express" callback. What is the best way to split out two different async operations into their own functions so that they can be used again together in a different callback?

I Have it working when I write everything inside the express callback

app.get('/', (req, res) => {
    axios.get('http://127.0.0.1:8080')                                                                                                                                                                                                                           
        .then(function(response) {                                                                                                                                                                                                                                    
            var http_data = response.data 
            // Do more stuff with data                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
            fs.readFile('fwversion_current', 'utf8', function(err, contents) {
            var file_data = contents.trim() 
            // Do more stuff with data
            if (http_data == file_data) {
                res.send("Match")
            }
            else {
                res.send("No Match")
            }
        });
});

But I'm hoping for something more like this so I can use these same operations in other places. I'm not sure the right node way to get there.

function getHttpData() {
    axios.get('http://127.0.0.1:8080')                                                                                                                                                                                                                            
        .then(function(response) {                                                                                                                                                                                                                                    
            var http_data = response.data 
            // Do more stuff with data    
            return http_data
         });
}

function getFileData() {
    fs.readFile('fwversion_current', 'utf8', function(err, contents) {                                                                                                                                                                                            
        var file_data = contents.trim() 
        // Do more stuff with data
        return file_data
    });
}

app.get('/', (req, res) => {
    let http_data = await getHttpData()
    let file_data = await getFileData()

    if (http_data == file_data) {                                                                                                                                                                                                                                 
        res.send("Match")                                                                                                                                                                                                                                     
    }                                                                                                                                                                                                                                                         
    else {                                                                                                                                                                                                                                                        
        res.send("No Match")                                                                                                                                                                                                                                  
    }                                                                                                                                         
});

1 Answer 1

1

You will need to wrap those functions inside a function that returns a Promise, this will let you the ability to await for them to complete before continuing.

function getHttpData(url) {
  // axios.get already returns a Promise so no need to wrap it
  return axios.get(url)
    .then(function(response) {
      let http_data = response.data;
      // Do more stuff with data
      return http_data;
    });
}

function getFileData(path) {
  return new Promise(function(resolve, reject) {
    fs.readFile(path, function(err, contents) {
      if (err) {
        reject(err);
        return;
      }
      let file_data = contents.trim();
      // Do more stuff with data
      resolve(file_data);
    });
  });
}

Now when both functions returns a Promise we can await for them to complete.

Make the handler an async function because it's needed to use the await keyword, I'm using Promise.all to fire both requests simultaneously and not wait for one to complete before we fire the other.

Wrap it in a try catch to handle errors and send status 500

app.get('/', async (req, res) => {
  try {
    const [http_data, file_data] = await Promise.all([
      getHttpData(url),
      getFileData(path),
    ]);

    http_data == file_data
      ? res.send('Match')
      : res.send('No Match');
  } catch (err) {
    console.error(err);
    res.status(500).send('Something went wrong');
  }
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.