【问题标题】:Promise returns early with a for loopPromise 通过 for 循环提前返回
【发布时间】:2014-03-07 17:38:12
【问题描述】:

我是 Promises 的新手,所以我可能在这里做了一些愚蠢的事情,但我似乎无法弄清楚。

只是为了让我知道我走在正确的道路上,提前提供一些信息。我有一个返回承诺的身份验证方法:

APIWrapper.prototype.authenticate = function() {
  var self = this;
  return new Promise(function(resolve, reject) {
    request({
      uri: self.httpUri + '/auth/authenticate',
      method: 'GET',
      headers: {
        auth_user: self.user,
        auth_pass: self.pass,
        auth_appkey: self.appkey
      }
    }, function(err, res, body) {
      if (err) return reject(err);
      self.parser.parseXML(body, function(err, result) {
        if (err) return reject(err);
        if (result.error) { return reject(result.error) }
        self.token = result.auth.token[0];
        return resolve(result);
      });
    });
  });
};

我把它与.getDashboards() 链接起来,如下所示:

wrapper.authenticate().then(function() {
  wrapper.getDashboards();
}).then(function(result) {
  console.log('result', result);
});

.getDashboards() 也返回一个承诺:

APIWrapper.prototype.getDashboards = function() {
  var self = this;
  return new Promise(function(resolve, reject) {
    request({
      url: self.httpUri + '/user/dashboard',
      method: 'GET',
      headers: {
        auth_appkey: self.appkey,
        auth_token: self.token
      }
    }, function(err, res, body) {
      if (err) { return reject('Could not connect to the API endpoint'); };
      self.parser.parseXML(body, function(err, data) {
        var dashboards = [];
        if(err) { return reject(err); }
        if(data.error) { return reject(data.error); }
        for(var i = 0; i < data.Dashboards.Dashboard.length; i++) {
          dashboards.push(self.getDashboard(data.Dashboards.Dashboard[i]));
        }
        // returns early here
        resolve(dashboards);
      });
    });
  });
};

现在使用像这样的.getDashboard() 方法:

APIWrapper.prototype.getDashboard = function(db) {
  var dashboard = {};
  dashboard.title = db.Title[0];
  dashboard.id = db.$.id;
  console.log(dashboard);
  return dashboard;
};

此代码发生的情况是它在返回仪表板之前返回result。我怀疑.getDashboards() 中的resolve() 不会等待for 循环完成?我是否也需要在 .getDashboard() 方法中使用承诺,或者在解决我的 .getDashboards() 承诺之前如何等待它完成?

输出:

> result undefined
{ title: 'Dashboard 1', id: '3271' }
{ title: 'Dashboard 2', id: '3272' }
{ title: 'Dashboard 3', id: '3273' }

我目前正在使用这个 Promise 实现:https://github.com/then/promise

【问题讨论】:

    标签: javascript node.js promise


    【解决方案1】:

    您需要返回承诺以将其链接起来:

    wrapper.authenticate().then(function() {
      return wrapper.getDashboards();
    }).then(function(result) {
      console.log('result', result);
    });
    

    在你的情况下,它可以简化为

    wrapper.authenticate()
    .then(wrapper.getDashboards)
    .then(function(result){
      console.log('result', result);
    });
    

    您似乎也不处理错误。 then 库在这一点上似乎非常原始,因此您可能应该添加第二个参数:

    wrapper.authenticate()
    .then(wrapper.getDashboards, onAuthenticateError)
    .then(function(result){
      console.log('result', result);
    }, onDashboardError);
    

    【讨论】:

    • 谢谢。不过,我似乎仍然没有理解关键部分。当我在我的 REPL 中尝试使用该代码时,它返回 { then: [Function] } 而不是记录 result 变量。
    • 你确定你写的不是return wrapper.getDashboards;而不是return wrapper.getDashboards();
    • 我用简化版测试过,好像不行。我现在测试了第一个 sn-p 并且有效。非常感谢!
    • 仅供参考:onError 只会捕获authenticate 方法的错误,不会捕获wrapper.getDashboards 的错误。
    猜你喜欢
    • 1970-01-01
    • 2019-03-25
    • 2020-11-28
    • 2018-06-07
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    相关资源
    最近更新 更多