使用Q在Node.js中同步诺言的麻烦

我目前在框架Sails.js Node.JS做一个API。 我第一次使用承诺,我有一些麻烦,像我想要的同步我的承诺。

我的主要function如下:

createCard: function(req, res) { checkIfUserHasStripeAccount(req.user) .then(addCreditCardToStripeAccount()) .then(function cardCreated() { res.send(200, { msg: 'Card created' }); }) .catch(function handleError(err) { res.send(err.httpCode, err.msg); }) }, 

很明显,如果用户没有信用卡,就无法将信用卡添加到条形账户。

函数checkIfUserHasStripeAccount()检查账户是否存在,如果没有,创build它。

这是这部分的代码:

 function checkIfUserHasStripeAccount(user) { var deferred = q.defer(); if (!user.idStripe) { createStripeAccountToUser(user) .then(function(savedUser) { deferred.resolve(savedUser); }) .catch(function(err) { deferred.reject(err); }) } else { deferred.resolve(user); } return deferred.promise; } function createStripeAccountToUser(user) { var deferred = q.defer(); var jsonUserToCreate = { description: user.firstname + ' ' + user.surname, email: user.email }; stripe.customers.create(jsonUserToCreate, function(err, customer) { if (err) { deferred.reject({ httpCode: 500, msg: 'some error' }); } else { user.idStripe = customer.id; user.save(function(err, savedUser) { if (err) { deferred.reject({ httpCode: 500, msg: 'some error' }); } deferred.resolve(savedUser); }); } }); return deferred.promise; } 

问题是.then(addCreditCardToStripeAccount())checkIfUserHasStripeAccount()完成之前执行。

我无法弄清楚为什么。 我认为.then(addCreditCardToStripeAccount())只有在收到拒绝或解决时才会被执行。

你的思路是正确的。 问题是你正在调用你的函数而不是引用它:

 .then(addCreditCardToStripeAccount()) 

应该:

 .then(addCreditCardToStripeAccount) 

我期望这个工作:

 createCard: function (req, res) { checkIfUserHasStripeAccount(req.user) .then(addCreditCardToStripeAccount) .then(function cardCreated(){ res.send(200, {msg: 'Card created'}); }) .catch(function handleError(err) { res.send(err.httpCode, err.msg); }) }, 

将来,请注意函数名称后面的()调用函数,因为在JS中执行的顺序将由于在()内部而首先进行计算。

在承诺链中,始终只调用第一个函数。 例:

 function first () { /*...*/ } // All return promise. function second() { /*...*/ } function third () { /*...*/ } first() // Invoked .then(second) // Not invoked. second() will have been bad here. .then(third);