node.js - ES7 - 如何用 await 替换 Promise?

标签 node.js express mongoose promise ecmascript-2017

有一件事让我对 Promise 感到反感,那就是它很难用 resolvereject 来掌握。包装 Promise 的需求也很难看。除非你经常使用它,否则我会随着时间的推移忘记如何使用它们。此外,带有 Promise 的代码仍然是凌乱且难以阅读的。因此我根本不喜欢使用它——因为它与回调 hell 没有太大区别。所以我想通过 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) {} 是来自 request nodejs 包的 AJAX 调用。

我必须用 Promise 包装它 - 但不能在它之前加上 await。理想情况下,这就是我的想象:

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

但如果我这样做,我将得到请求对象作为返回,而不是request包返回的数据——在这一行:

const data = await getWeather();

有什么想法或解决方案可以避免在上述情况下使用 Promise 吗?

最佳答案

您会发现 bluebird 和 node.js 现在带有 promisify,允许您在需要时将 Node 回调作为 promise 使用。或者,您可以考虑一种功能性响应式(Reactive)方法并使用像 RxJS 这样的库,它将处理 promise 、 Node 回调和其他数据类型到流中。

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

关于node.js - ES7 - 如何用 await 替换 Promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44908198/

相关文章:

node.js - 获取 connect-redis 上现有 session 的列表

node.js - SailsJs 中填充了什么?

node.js - 浏览器不发回cookie,但curl却发回

node.js - Node.js 获取 mongoose 回调函数的返回值

node.js - Mongoose 模式方法返回不是一个函数

node.js - Mongoose 私聊消息模型

在开始下一个之前等待上一个 promise 的 Javascript Map?

node.js - 防止快速主体解析器在 request.pipe 之前删除主体

node.js - MongoDB - 连接模型中的两个属性并用结果更新模型

node.js - 如何用 mongoose 区分填充的集合