带有 Stripe 和 MongoDB 集成的 GraphQL 突变过早返回 null [重复]

Posted

技术标签:

【中文标题】带有 Stripe 和 MongoDB 集成的 GraphQL 突变过早返回 null [重复]【英文标题】:GraphQL mutation with Stripe and MogoDB integration returns null too early [duplicate] 【发布时间】:2018-03-02 20:33:11 【问题描述】:

我正在尝试在 GraphQL 中创建一个突变,向用户收取 Stripe 费用,但我无法让用户返回客户端。一切在我的数据库中运行良好,付款已完成,但在我的客户端,.then() 过早触发,结果为 null,而它应该返回我编辑的用户。它实际上是在我的服务器上的 stripe.charges 完成之前触发的。

服务器端:

chargeUser(args) 
    const  userId, membershipId, stripeToken  = args;

    return User.findById(userId)
        .then((user) => 
            return Membership.findById(membershipId)
                .then((membership) => 
                    return stripe.charges.create(
                        amount: membership.price * 100,
                        currency: 'chf',
                        source: stripeToken,
                        description: `$user.firstname $user.lastname`
                    , function(err) 
                        if (!err) 
                            user.membership = membershipId;
                            return user.save();
                         else 
                            console.log(err)
                        
                    );
                )
        );

客户端:

this.props.mutate(
    variables: 
        membershipId: this.props.membershipId,
        userId: global.userId,
        stripeToken: token.tokenId
    
)
.then((res) => 
    // Returning null before the stripe.charges has finished
    console.log(res)
)

【问题讨论】:

【参考方案1】:

这里的问题是stripe.charges.create() 使用了回调;它不返回承诺。与 Promise 不同,在回调中返回用户不会做任何事情——你的 Promise 链在返回值 stripe.charges.create() 处终止,它为 null。

为了让你的解析器等待回调,你必须将它包装在一个承诺中,像这样:

return User.findById(userId)
  .then((user) => 
    return Membership.findById(membershipId)
      .then((membership) => 
        return new Promise((resolve, reject) => 
          stripe.charges.create(
            amount: membership.price * 100,
            currency: 'chf',
            source: stripeToken,
            description: `$user.firstname $user.lastname`
          , (err) => 
            err ? reject(err) : resolve()
          )
        )
      )
      .then(() => user.save())
  )

或者,使用 async/await 稍微清理一下:

const chargeUser = async (args) => 
    const  userId, membershipId, stripeToken  = args;

    const user = await User.findById(userId)
    const membership = await Membership.findById(membershipId)
    await new Promise((resolve, reject) => 
      stripe.charges.create(
        amount: membership.price * 100,
        currency: 'chf',
        source: stripeToken,
        description: `$user.firstname $user.lastname`
      , (err) => 
        err ? reject(err) : resolve()
      )
    )
    return user.save()

【讨论】:

以上是关于带有 Stripe 和 MongoDB 集成的 GraphQL 突变过早返回 null [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Android Firebase 和 Stripe 集成

Stripe 定期支付与 masterpass 集成

是否可以将 Stripe 与 Firebase 和 iOS 集成?

Stripe API 测试自动化

如何使用 React Native 集成 Stripe 并符合 PCI 标准?

iOS Parse Stripe 集成