【问题标题】:How to wait for sub process results before returning from Meteor.method如何在从 Meteor.method 返回之前等待子流程结果
【发布时间】:2012-05-02 07:52:51
【问题描述】:

我有点惊讶Meteor.method 定义需要返回结果而不是调用回调。但事实就是如此!

我正在尝试在 Meteor 中创建一个调用 mongoose 组方法的 RPC 方法(看起来流星的数据 api 不允许我这样做,所以我正在解决它)。我有这样的事情:

Meteor.methods
  getdata: ->
    mongoose = __meteor_bootstrap__.require('mongoose')
    db = mongoose.connect(__meteor_bootstrap__.mongo_url)
    ASchema = new mongoose.Schema()
    ASchema.add({key: String})
    AObject = mongoose.model('AObject',ASchema)
    AObject.collection.group(
      ...
      ...
      (err,doc) -> # mongoose callback function
         # I want to return some variation of 'doc'
    )
    return ??? # I need to return 'doc' here.

我自己对上面发布的代码的变体确实有效...我接到了来自我的流星客户端的电话,猫鼬对象都发挥了它们的魔力。但我不知道如何让我的结果在原始上下文中返回。

我该怎么做?


我的答案会让我的代码看起来像这样:

require = __meteor_bootstrap__.require
Meteor.methods
  getdata: ->
    mongoose = require('mongoose')
    Future = require('fibers/future')
    db = mongoose.connect(__meteor_bootstrap__.mongo_url)
    ASchema = new mongoose.Schema()
    ASchema.add({key: String})
    AObject = mongoose.model('AObject',ASchema)
    group = Future.wrap(AObject.collection.group,6)
    docs = group.call(AObject,collection,
      ...
      ...
    ).wait()
    return docs

【问题讨论】:

    标签: javascript mongodb coffeescript meteor


    【解决方案1】:

    啊……想通了。在谷歌搜索和谷歌搜索并按照“不要那样做,使用回调!”的思路找到过多的 cmets 之后,我终于找到了它:使用fibers

    我最终使用了fibers-promise 库。我的最终代码如下所示:

    Meteor.methods
      getdata: ->
        promise = __meteor_bootstrap__.require('fibers-promise')
        mongoose = __meteor_bootstrap__.require('mongoose')
        db = mongoose.connect(__meteor_bootstrap__.mongo_url)
        ASchema = new mongoose.Schema()
        ASchema.add({key: String})
        AObject = mongoose.model('AObject',ASchema)
        mypromise = promise()
        AObject.collection.group(
          ...
          ...
          (err,doc) -> # mongoose callback function
             if err
               mypromise.set new Meteor.Error(500, "my error")
               return
             ...
             ...
             mypromise.set mydesiredresults
        )
        finalValue = mypromise.get()
        if finalValue instanceof Meteor.Error
          throw finalValue
        return finalValue
    

    【讨论】:

    • 你可以接受你自己的答案,我认为这是合理的。不过,您可能需要先等待一段时间。
    • 很抱歉 - 我在那里兴奋了一分钟,无法自拔。
    • 我不是在抱怨,我建议您接受自己的答案,以便将来的搜索者更容易解决类似问题。
    • 哦,对了,呵呵。好吧,再过 2 天我不会这样做,但我会的,谢谢。
    【解决方案2】:

    使用fibers/future 模块可能会为您提供更好的Meteor API,因为这是内部使用的API,并且它随任何香草流星安装一起提供。

    以你为例:

    require  = __meteor_bootstrap__.require
    Future   = require 'fibers/future'
    mongoose = require 'mongoose'
    
    Meteor.methods
      getdata: ->
        db = mongoose.connect(__meteor_bootstrap__.mongo_url)
        ASchema = new mongoose.Schema()
        ASchema.add({key: String})
        AObject = mongoose.model('AObject',ASchema)
    
        # wrap the method into a promise
        group = Future.wrap(AObject.collection.group)
    
        # .wait() will either throw an error or return the result
        doc = group(... args without callback ...).wait()
    

    【讨论】:

    • 听起来不错,我试试看。
    • 如果你尝试 doc = group.call(AObject.collection, ...args without callback...).wait() 而不是 doc = group(...args without callback... ).wait(),你还会遇到同样的异常吗?
    • Arg,抱歉跑来跑去。所以我发布的第一个错误 (Object #...) 是当我试图包装一个“AObject.find”调用时。我尝试将 AObject 传递给它,但运气不佳(上面的错误类型相同)。然后我尝试了 AObject.collection.group,就像我在帖子中写的那样,它给了我这个错误:函数期望不超过 -1 个参数。我尝试将 AObject.collection 作为参数放入并得到相同类型的错误。
    • 'requires no more than -1 arg'的错误很常见。这是因为您在没有参数的情况下调用了包装的方法。在这些情况下,您需要将要包装的方法的数量作为第二个参数:Future.wrap(Aboject.collection.group, 0)... 其中 0 是函数的数量(因为它需要 0 个参数和回调 - 根据需要进行更改)。 TypeError ('has no method...) 听起来 this 的值未设置为您期望的值,这就是为什么我建议执行 find.call(AObject, args...) 之类的操作。我希望这会有所帮助,我需要查看/与您的代码交互以更进一步......
    • 谢谢,我让它工作了,因为它不需要创建额外的包,所以我选择它。
    【解决方案3】:
    猜你喜欢
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2017-08-05
    • 1970-01-01
    相关资源
    最近更新 更多