javascript - Promise 通过 for 循环提前返回

标签 javascript node.js promise

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

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

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() 也返回一个 promise :

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() 方法中使用 promises,或者在解决我的 .getDashboards() promise 之前,我将如何等待它完成?

输出:

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

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

最佳答案

您需要返回将其链接起来的 promise :

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

关于javascript - Promise 通过 for 循环提前返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22166744/

相关文章:

java - nodejs child_process exec 'java -version'

node.js - 使用 Node js 将 S3 视频转换为音频文件(Lambda 函数)

javascript - 如何将文件夹中的所有图像放入 CSS 框

javascript - JQuery 遍历多个/所有具有特定名称的 HTML 元素

javascript - 带有 jQ​​uery 的 HTML 文件选择器

javascript - 将 ALMA 算法转换为 JavaScript

javascript - 将基于 JavaScript/HTML 的应用程序上传到 Heroku

javascript - 从 Backbone 模型返回 promise

javascript - 有没有一种直接的方法可以让集合上的 jQuery 动画创建一个新的 promise ?

javascript - Q Promise同步应答