ES7 - how can I replace a Promise with an expectation?

One thing that turns me off with Promise is that it is difficult to understand with resolve

and reject

. Also the need for wrapping Promise

is ugly. If you don't use it very often, I tend to forget how to use them over time. Plus, the code Promise

is still messy and hard to read. So I don't really like using it at all, because it's not much different from a callback addon. So I thought that with ES7 await

I might be able to avoid using Promise and believe even more in JavaScript, but it doesn't seem to be the case. For example:

const getOne = async () => {
    return Weather.findOne(options, function(err, weather) {
        //
    });
}
const getWeather = async () => {
    const exist = await getOne();
    if (exist == null) {
        return new Promise(function(resolve, reject) {
            // Use request library.
           request(pullUrl, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    // Resolve with the data.
                    resolve(body);
                } else {
                    // Reject with the error.
                    reject(error);
                }
            });
        });
    }
}

const insertWeather = async () => {
    try {
        const data = await getWeather();
    } catch (err) {
        res.set('Content-Type', 'application/json');
        return res.status(200).send('Error occurs: ' + err);
    }
}
insertWeather();

      

request(pullUrl, function (error, response, body) {}

is an AJAX call from the request package for nodejs.

I have to wrap it with Promise

- but not preface it await

. Ideally, this is what I imagine:

return await request(pullUrl, function (error, response, body) {...}

      

But if I do that, I will return to the request object instead of the data from the package request

- in this line:

const data = await getWeather();

Any ideas or solutions to avoid using Promise

the case like above?

+3


source to share


2 answers


You will now see bluebird and node.js come with a promise so you can consume Node callbacks as promises when you need it too. Alternatively, you can consider a functional reactive approach and use a library like RxJS that will handle promises, Node and other data types callbacks in streams.



const promisify = require('utils').promisify // alternatively use bluebird
const request = require('request-promise');

const weatherFn = promisify(Weather.findOne);

const weatherOptions = {};

async function getWeatherIfDoesNotExist() {

 try {
   const records = await weatherFn(weatherOptions);

   if (records === null) {
     return await request('/pullUrl');
   }

 } catch(err) {
   throw new Error('Could not get weather');
 }
}

async function weatherController(req, res) {
  try {
    const data = await getWeatherIfDoesNotExist();
  } catch (err) {
    res.set('Content-Type', 'application/json');
    return res.status(200).send('Error occurs: ' + err);
  }
}

function altWeatherController(req, res) {

  return getWeatherIfDoesNotExist()
    .then((data) => { // do something })
    .catch((err) => {
      res.set('Content-Type', 'application/json');
      return res.status(200).send('Error occurs: ' + err);
    })
}

      

+3


source


As mentioned in the documentation here , you need to wrap with request

interface wrappers like request-promise (or you can find an alternative interface in the documentation) in order to return a Promise from request

.



+1


source







All Articles