ES7 - 如何用等待取代Promise?

时间:2017-07-04 14:10:13

标签: node.js express mongoose promise ecmascript-2017

有一件事让我想起承诺是因为resolvereject很难掌握。包裹Promise的需求也很难看。除非你经常使用它,否则我会忘记如何随着时间的推移使用它们。此外,Promise的代码仍然很混乱,难以阅读。因此我根本不喜欢使用它 - 因为它与回调地狱没什么不同。所以我想到ES7 await,我可以避免使用 Promise 并让我对JavaScript有更多的信心,但似乎并非如此。例如:

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) {}是针对nodejs的request包的AJAX调用。

我必须使用Promise 打包 - 但不要在await之前。理想情况下,这就是我的想象:

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

但是,如果我这样做,我会在此行获得请求对象,而不是从request包中返回的数据

const data = await getWeather();

避免在上述情况下使用Promise的任何想法或解决方案?

2 个答案:

答案 0 :(得分:5)

您会发现bluebird和node.js现在都带有promisify,允许您在需要时使用Node回调作为承诺。或者,您可以考虑使用功能性反应方法,并使用像RxJS这样的库,它将承诺,节点回调和其他数据类型处理成流。

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);
    })
}

答案 1 :(得分:1)

如文档here中所提到的,您需要使用request-promise之类的接口包装器包装request(或者您可以在文档中找到替代接口)以便返回Promise来自request