【问题标题】:Where am I going wrong using promises and async?使用 Promise 和异步我哪里出错了?
【发布时间】:2019-11-02 10:33:20
【问题描述】:

我在 'apiCalls.js' 文件中编写了一个函数,并具有以下功能:

function getAllData() {
  new Promise(function(resolve, reject) {
    async.parallel([
      function(callback) {
        request('http://urlcall', function(error, response, body) {
          if(!error && response.statusCode == 200) {
            return callback(null, body);
          }
          return callback(error || new Error('Response non-200'));
        });
      },
      function(callback) {
        request('http://urlcall', function(error, response, body) {
          if(!error && response.statusCode == 200) {
            return callback(null, body);
          }
          return callback(error || new Error('Response non-200'));
        });
      },
    ],
    function(err, results) {
      if(err) {
        console.log(err);
        reject(err);
      }
      console.log(results);
      resolve(results);
    });
  });
}

然后我在我的 app.js 文件中调用这个函数:

apiCalls.getAllData().then(function(returned) {
    console.log(returned);
    res.render('home');
  });

我收到一个错误,其中返回的值未定义: TypeError: Cannot read property 'then' of undefined

我不确定我哪里出错了。我已经解决了承诺,然后在 then 函数中使用了该值。我在这里错过了什么吗?我不熟悉使用 Promise 和异步编程,所以我在这里错过了一些关于它应该如何工作的理解?

【问题讨论】:

  • 一方面,您没有从getAllData() 函数返回承诺。你可以试试return new Promise ...
  • 把 promises 和 async 一起使用会出错——这两种风格不能很好地混合。请改用request-promisePromise.all

标签: javascript node.js asynchronous promise


【解决方案1】:

首先,您真的不想将 Promise 与普通回调与 async 库混为一谈。您需要选择一种模型来使用(承诺或回调)并将所有控制流编程到一个模型中。因此,如果您要转向 Promise(世界上大多数地方都是如此),那么请完全跳过异步库。在这种特殊情况下,Promise.all() 为您的两个并行请求服务。

然后,寻找承诺您拥有的最低级别的异步操作,因为它允许您将承诺用于所有控制流和错误处理。在您的情况下,这就是请求库,它已经有一个名为 request-promise 的承诺版本。此外,它已经自动为您检查非 2xx 状态(并拒绝承诺),因此您不必编写代码。所以,看来你可以用这个替换你拥有的所有东西:

const rp = require('request-promise');    // promise version of the request library

function getAllData() {
    return Promise.all([rp('http://urlcall1'), rp('http://urlcall2')]);
}

然后,您可以将其与.then() 一起使用:

apiCalls.getAllData().then(returned => {
    console.log(returned);
    res.render('home', returned);
}).catch(err => {
    console.log(err);
    res.sendStatus(500);
});

【讨论】:

  • 谢谢你,这是对我得到的承诺最好的解释!
猜你喜欢
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 2013-12-25
  • 2018-02-21
  • 2017-09-20
  • 1970-01-01
相关资源
最近更新 更多