Meteor 方法调用在客户端上返回未定义,但在服务器上不返回



>UPDATE

我刚刚意识到这种方法存在根本性错误,嵌套回调无法向其父回调返回某些内容。我在JS世界很晚,来自Promises时代,不知道这是回调的问题。但是我没有看到足够多的例子 Meteor 使用 promise 所以我使用了回调。但是,如果可以改进此代码,我将不胜感激。

问题

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

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(中我仍然一无所知。

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

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;
  }
})
这就是

我使用 Promise 和 Meteor 1.3+ 的新async/await功能解决问题的方式

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
    })())
  }
})

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

最新更新