使用 Q 在 Node.js 中同步 Promise 的麻烦
Posted
技术标签:
【中文标题】使用 Q 在 Node.js 中同步 Promise 的麻烦【英文标题】:Trouble to synchronise promises in Node.js using Q 【发布时间】:2015-12-31 04:49:55 【问题描述】:我目前正在使用框架 Sails.js 在 Node.JS 中做一个 API。我是第一次使用 Promise,但在同步我的 Promise 时遇到了一些麻烦。
我的主要功能如下:
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() 检查帐户是否存在,如果不存在,则创建它。
这是这部分的代码:
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())
只有在收到拒绝或解决时才会执行。
【问题讨论】:
【参考方案1】:你的思路是对的。 问题是您正在调用您的函数而不是引用它:
.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 中的执行顺序将首先评估它,因为它位于 then 的 ()
内。
在 Promise 链中,始终只调用第一个函数。示例:
function first () /*...*/ // All return promise.
function second() /*...*/
function third () /*...*/
first() // Invoked
.then(second) // Not invoked. second() will have been bad here.
.then(third);
【讨论】:
我试过你告诉我的,它有效。非常感谢 !但是,它产生了另一个问题。我希望我的函数 addCreditCardToStripeAccount 采用 2 个参数。我做了一些实验,似乎 deferred.resolve() 只能携带 1 个参数。那是对的吗 ?我是否必须改用对象或数组之类的复合值? 如果您使用的是bluebird,您可以使用数组,并将.then()
替换为.spread()
。我不确定本地承诺。我是AFK,但我可以帮上忙。乐意效劳。 :)以上是关于使用 Q 在 Node.js 中同步 Promise 的麻烦的主要内容,如果未能解决你的问题,请参考以下文章
在 Node.js 中进行同步 MongoDB 查询的正确方法是啥?
promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解