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?
source to share
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);
})
}
source to share
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
.
source to share