Home > Software design >  Cannot get the result of an async function in controller
Cannot get the result of an async function in controller

Time:10-19

This is my controller:

const rssService = require('../services/rss.service');

async function parser() {
  const result = await rssService.rssParser('someurl');
  return result;
};

const parse = async function (req, res) {
  const p = new Promise((resolve, reject) => {
    const t = parser();
    if (t === undefined) {
      resolve(t);
    } else {
      // eslint-disable-next-line prefer-promise-reject-errors
      reject('something bad happened');
    }
  });

  p.then((result) => res.send(result)).catch((message) => console.log(`ERROR ${message}`));
};

module.exports = {
  parse,
};

in the function : parser() above, I am trying to call my rss.service.js file which I have the logic. This file is a rss parser which tries to parse the feed and do some calculations (which needs promises and async) and then return the json object.

Here is how my rss.service look :

const rssParser = async function parseRssFeed(url) {
  const parser = new Parser();
  const appRoot = process.env.PWD;
  const downloadDir = `${appRoot}/downloads/`;

  if (!fs.existsSync(downloadDir)) {
    fs.mkdirSync(downloadDir);
  }

  try {
    const feed = await parser.parseURL('someurl');
    const processedFeedItems = await Promise.all(feed.items.map(async (currentItem) => {
      const {
        fileUrl,
        downloadPath,
      } = await downloadFile(currentItem);

      const hashValue = calculateHash(downloadPath)
      return {
        title: currentItem.title,
        hash: hashValue,
        url: mp3FileUrl,
      };
    }));
    return (JSON.stringify(processedFeedItems));
  } catch (error) {
    console.error(error);
    return 'error';
  }
};

when I debug my code I can verify that Json object has been created with correct data, but the result does not return to the callee(controller).

CodePudding user response:

I'll go in a little deeper since you mentioned you're new:

const rssService = require('../services/rss.service');

// This is an async function (always returns a promise)
async function parser() {
  const result = await rssService.rssParser('someurl');
  return result;
};

const parse = async function (req, res, next) {
  // In await/async, you should use try/catch/throw instead of .then and .catch
  // It does the same thing, but it's the preferred syntax and is "easier" to read IMO
  // Out in "the community" people will complain if you mix await/async with promises like that
  try {
    // Adding await to ensure left-assign works.
    // This is necessary because parser is an async function (so returns a promise)
    const result = await parser();
    // here, since you used `await` you get the value instead of the promise
    if (result === undefined) throw new Error('something bad happened')
    return res.send(result)
  } catch (error) {
    console.log(`ERROR ${error.message}`;
    // Do you need to do anything else with this error? I assume something like:
    return next(error);
  }
};

module.exports = {
  parse,
};

CodePudding user response:

In a fast look, It seems you have forgot to wait for resolve the parser promise.

...
const p = new Promise(async(resolve, reject) => {
   const t = await parser();
   ...
  • Related