Meteor方法调用在客户端上返回undefined但在服务器上没有返回

时间:2017-02-08 05:20:13

标签: javascript meteor meteor-accounts

更新

我刚刚意识到这种方法存在根本错误,嵌套回调无法向其父回调返回一些内容。我来自JS世界的后期来自Promises时代,并且不知道这是回调的问题。但我没有看到Meteor使用promises的足够示例,所以我使用了回调。但是,如果可以改进此代码,我会非常感激。

问题

所以我使用以下方法从客户端调用方法:

Meteor.call('cart.useProfileAddress', {}, (error, address) => {
  console.info('Address', address) // this returns undefined on client
})

这是我api/carts/cartsMethod.js

中的方法
export const useProfileAddress = new ValidatedMethod({
  name: 'cart.useProfileAddress',
  validate(args) {
    //
  },
  run(args) {
    const person = Persons.findOne({'userId': Meteor.userId()});
    // If I do the return here I get the address in the browser as defined.
    // return person.address

    // I'm calling another method under here:
    getClosestStore.call({address: person.address}, (error, result) => {
      // And another one method call here:
      updateCartAddress.call({address: person.address}, (error, result) => {
        // So once all the callbacks are done return the address here.
        // However the problem is I get `undefined` on the client.
        if (!error) {
          // console displays something on the Server but is `undefined` on the Client
          console.info('Returning Address', person.address)
          return person.address
        }
      })
    })
  }
})

上面的代码可能有什么问题?可能是因为我试图从嵌套回调中获取值吗?

还有谁知道如何避免这些嵌套回调?我知道如何在Node上使用承诺,但在Meteor中(我使用1.4),我仍然无能为力。

2 个答案:

答案 0 :(得分:4)

方法可以在服务器上同步运行,因此您不需要使用回调。执行后将返回方法的结果,否则将在发生错误时抛出异常。试试这个:

export const useProfileAddress = new ValidatedMethod({
  // ...
  run(args) {
    const person = Persons.findOne({'userId': Meteor.userId()});

    const result1 = getClosestStore.call({address: person.address});

    // use result1 if you need to

    const result2 = updateCartAddress.call({address: person.address});

    // // use result2 if you need to

    return person.address;
  }
})

答案 1 :(得分:3)

这是我使用Promise和Meteor async/await的新1.3+功能解决我的问题的方法export const useProfileAddress = new ValidatedMethod({ name: 'cart.useProfileAddress', validate(args) { // }, run(args) { return ((async () => { const person = Persons.findOne({'userId': Meteor.userId()}); const storeId = await getClosestStore.callPromise({address: person.address}) const newAddress = await updateCartAddress.callPromise({address: person.address}) return newAddress })()) } })

{{1}}

在每个方法中,我使用didericis:callpromise-mixin,以便它返回一个承诺。