Accounts.onCreateUser 中的流星承诺

Meteor Promises in Accounts.onCreateUser

我想在 meteor 用户注册期间创建一个 stripe 帐户,并为此目的调整 Accounts.onCreateUser 并承诺。

Accounts.onCreateUser((options, user) => {
  if (user.services.facebook) {
    const { first_name, last_name, email } = user.services.facebook;
    user.profile = {}
    user.profile.first_name = first_name
    user.profile.last_name = last_name

  }
  else{
    user.profile = options.profile
  }
  user.stripe = {}
  return new Promise((resolve,reject) => {
    stripe.customers.create({
      description: user.profile.first_name + ' ' + user.profile.last_name
    },function(err,response){

        if (!err) {
          user.stripe.id = response.id
          resolve(user);
        } else {
          reject('Could not create user');
        }

    });
  })
});

虽然在 stripe 中正确创建了用户,但 meteor mongo 数据库中的用户文档仅包含用户 ID 而没有其他字段。

我是不是用错了promise?如有任何帮助,我们将不胜感激!

是的,您创建了承诺,但没有等到它解决。到时候 onCreateUser 早就回来了。试试这个:

function createStripeUser(user) {
  return new Promise((resolve,reject) => {
    stripe.customers.create({
      description: user.profile.first_name + ' ' + user.profile.last_name
    },function(err,response){
        if (!err) {
          user.stripe.id = response.id
          resolve(user);
        } else {
          reject(err);
        }
    });
  })
}

Accounts.onCreateUser(async (options, user) => {
  if (user.services.facebook) {
    const { first_name, last_name, email } = user.services.facebook;
    user.profile = {}
    user.profile.first_name = first_name
    user.profile.last_name = last_name
  }
  else {
    user.profile = options.profile
  }
  user.stripe = {}
  try {
    return await createStripeUser(user);
  } catch(e) {
    // handle your error
  }
});

因为 onCreateUser 运行 在服务器上,我们可以使用 Meteor.wrapAsync.

将 Stripe 调用包装在 Fiber 中

Fibers 允许异步代码 运行 就好像它是同步的一样,但只在服务器上。 (Here's a great presentation on what Fibers are and why Meteor uses them)

使用 wrapAsync 代码如下所示:

Accounts.onCreateUser((options, user) => {
  if (user.services.facebook) {
    const { first_name, last_name, email } = user.services.facebook;
    user.profile = {}
    user.profile.first_name = first_name
    user.profile.last_name = last_name
  } else {
    user.profile = options.profile
  }

  user.stripe = {};
  const createStripeCustomer = Meteor.wrapAsync(stripe.customers.create,stripe.customers);
  const response = createStripeCustomer({
      description: user.profile.first_name + ' ' + user.profile.last_name
  });
  user.stripe.id = response.id
  return user;
});