admin管理员组

文章数量:1024884

I'm kinda surprised that the Meteor.method definitions require a result to be returned rather than a callback be called. But so it is!

I'm trying to make an RPC method in Meteor that calls mongoose group methods (It didn't look like meteor's data api lets me do it so I'm working around it). I have something like this:

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.

My own variation of the code posted above does work...I get calls from my meteor client, the mongoose objects all work their magic. But I can't figure out how to get my results to return within the original context.

How can I do this?


The answer I went with would make my code look like this:

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

I'm kinda surprised that the Meteor.method definitions require a result to be returned rather than a callback be called. But so it is!

I'm trying to make an RPC method in Meteor that calls mongoose group methods (It didn't look like meteor's data api lets me do it so I'm working around it). I have something like this:

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.

My own variation of the code posted above does work...I get calls from my meteor client, the mongoose objects all work their magic. But I can't figure out how to get my results to return within the original context.

How can I do this?


The answer I went with would make my code look like this:

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
Share Improve this question edited Apr 26, 2012 at 2:29 dsummersl asked Apr 20, 2012 at 17:55 dsummersldsummersl 6,76752 silver badges67 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

Ah...figured it out. After googling and googling and finding inordinate numbers of ments along the lines of "don't do it that way, use callbacks!", I finally found it: use fibers!

I ended up using the fibers-promise library. My final code looks something like this:

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

Check out this amazing gist with a collection of example.

Using the fibers/future module may give you a better API for Meteor as this is what is used internally, and it es with any vanilla meteor install.

To take your example:

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

I'm kinda surprised that the Meteor.method definitions require a result to be returned rather than a callback be called. But so it is!

I'm trying to make an RPC method in Meteor that calls mongoose group methods (It didn't look like meteor's data api lets me do it so I'm working around it). I have something like this:

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.

My own variation of the code posted above does work...I get calls from my meteor client, the mongoose objects all work their magic. But I can't figure out how to get my results to return within the original context.

How can I do this?


The answer I went with would make my code look like this:

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

I'm kinda surprised that the Meteor.method definitions require a result to be returned rather than a callback be called. But so it is!

I'm trying to make an RPC method in Meteor that calls mongoose group methods (It didn't look like meteor's data api lets me do it so I'm working around it). I have something like this:

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.

My own variation of the code posted above does work...I get calls from my meteor client, the mongoose objects all work their magic. But I can't figure out how to get my results to return within the original context.

How can I do this?


The answer I went with would make my code look like this:

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
Share Improve this question edited Apr 26, 2012 at 2:29 dsummersl asked Apr 20, 2012 at 17:55 dsummersldsummersl 6,76752 silver badges67 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

Ah...figured it out. After googling and googling and finding inordinate numbers of ments along the lines of "don't do it that way, use callbacks!", I finally found it: use fibers!

I ended up using the fibers-promise library. My final code looks something like this:

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

Check out this amazing gist with a collection of example.

Using the fibers/future module may give you a better API for Meteor as this is what is used internally, and it es with any vanilla meteor install.

To take your example:

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

本文标签: javascriptHow to wait for sub process results before returning from MeteormethodStack Overflow