【问题标题】:JS Promises - End of Chain Returning before Chain StepJS Promises - 在链步之前返回链的结束
【发布时间】:2017-04-24 03:21:45
【问题描述】:

我有一个由数据库查询和 API 调用组成的承诺链。我正在尝试运行这些进程,然后将它们存储为我可以在我的视图中使用的对象,但看起来我的链呈现最后一步的速度比从stripe.customers.retrieve 部分中提取的值要快,这阻止了我从恢复该方法返回的对象。例如,参见终端输出部分。这可能是我对 Promises 的误解,但链接不应该按从上到下的顺序调用项目吗?有没有办法防止在stripe.customers.retrieve 完成之前呈现最后一条链?

承诺链:

var account;
var card;
var customerInfo;
var test;

models.Account.findOne({
    ...
}).then(function(_account){
    console.log('Here is the account: ' + _account);
    account = _account;
    return stripe.customers.retrieveCard(account.customerId, account.cardId, {
        function(err, account){
            if (err){
                return console.log(err);
            } else {
                return console.log(account);
            }
        }
    }).then(function(_card){
        console.log('Here is the card: ' + _card);
        card = _card;
        return stripe.customers.retrieve(account.customerId, function(err, customer){
            if (err){
                return console.log(err);
            } else {
                return console.log('Customer is returned ' + customer)
            }
        }).then(function(_customer){
            customerInfo = _customer;
            console.log('Returned value ' + _customer);
            console.log('Current card' + card);
            console.log('Current customer ' + customerInfo);
            res.render('pages/app/settings-billing.hbs', {
                ...
            });
        });
    });
}).catch(function(err){
    console.log(err);
});

终端输出:

Here is the account: [object SequelizeInstance:account]
Here is the card: [object Object]
Returned value undefined
Current card[object Object]
Current customer undefined
Customer is returned [object Object]

【问题讨论】:

  • 我认为你嵌套了两个承诺!
  • 那些条带方法可能没有返回承诺,return console.log() 也没有意义。条带方法的文档在哪里使用?
  • 他们不是,这里是文档stripe.com/docs/api/node#retrieve_customer。但是我在stripe.customers.retrieve 之前有一个条带调用,它在我的承诺链的上下文中工作
  • 需要为两个条带方法返回承诺并在条带方法回调中解析/拒绝它们
  • @charlietfl 谢谢你的建议。您介意在下面的答案中显示您将做出的改变吗?

标签: javascript node.js promise


【解决方案1】:

在每个条带方法上使用 then() 而不是回调,这样您就可以从每个方法返回一个承诺。

对此进行了一些修改,以继续将一个对象传递到最后,而不是使用全局变量

models.Account.findOne({
    ...
  })
  .then(function(_account) {
    let data = {
      account: _account
    }
    return stripe.customers.retrieveCard(_account.customerId, _account.cardId).then(function(card) {          
      data.card = card;
      return data;
    });
  })
  .then(function(data) {
    console.log('Here is the card: ' + data.card);
    return stripe.customers.retrieve(data.account.customerId).then(function(customer) {
      data.customer = customer;
      return data
    });
  })
  .then(function(data) {
    console.log(JSON.stringify(data, null, ' '));

  }).catch(function(err) {
    console.log(err);
  });

【讨论】:

    【解决方案2】:

    答案如下: 您需要以期望返回值的方式调用您的承诺。 你做错了什么是你有嵌套的承诺。 背后的想法是,您调用一个承诺,并在它实现时解析该值。

    models.Account.findOne({
        ...
    })
    .then(function(_account){
        console.log('Here is the account: ' + _account);
        account = _account;
    
        return stripe.customers.retrieveCard(account.customerId, account.cardId, {
            function(err, account){
                if (err){
                    return console.log(err);
                } else {
                    return console.log(account);
                }
            }
        });
    })
    .then(function(_card){
         console.log('Here is the card: ' + _card);
         return stripe.customers.retrieve(account.customerId, function(err, customer){
             if (err){
                    return console.log(err);
                } else {
                    return console.log('Customer is returned ' + customer)
                }
            });
    })
    .then(function(_customer){  
                    customerInfo = _customer;
                console.log('Returned value ' + _customer);
                console.log('Current card' + card);
                console.log('Current customer ' + customerInfo);
                res.render('pages/app/settings-billing.hbs', {
                    ...
                });
    }).catch(function(err){
        console.log(err);
    });
    

    【讨论】:

    • " think should be like this" 没有解释有什么不同或为什么您认为您的代码会有所帮助。
    • 我没有node环境可以测试,但是概念有!
    • 只有代码没有解释的答案在这里没有什么价值
    • 我对我的答案进行了编辑。希望我这次确实解释得很好!
    • 感谢您的回答,但取消嵌套承诺不会改变问题。
    猜你喜欢
    • 1970-01-01
    • 2015-04-15
    • 2017-04-03
    • 2016-08-31
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多