2013-07-04 17 views
31

私は流星0.6.4を使用しています。Meteor.methods returns undefined

Meteor.methods({ 
    random: function(top){ 
    var random = Math.floor((Math.random()*(top+1))); 
    return random; 
    } 
}); 

私はこれを乗り越えることができる方法

Meteor.call('random', 10); 

任意のアイデアを実行するたびにそれはundefinedを返しますか?

答えて

57

これは完全に正常な動作です:

クライアントでは、あなたがコールバックを渡さないと、あなたはスタブ内でない場合、呼び出しが返されます:サーバーの方法は、流星のコールは非同期にdocumentedです定義されていないため、メソッドの戻り値を取得する方法がありません。

それはあなたのサーバー上でリモートで実行するMeteor.call方法を尋ねたときに、ローカルメソッド呼び出しが非ブロッキングがあると、すぐにundefinedを返すことを意味します。

Meteor.call("myMethod", arguments..., function(error, result){ 
    if(error){ 
    console.log(error.reason); 
    return; 
    } 
    // do something with result 
}); 

匿名のコールバック関数ができるだけ早くクライアント上で呼び出されます:メソッドは、コールバックのパターンを使用して、それを取得する必要がありますので、それは、クライアントに非同期に結果を送信するサーバー上で呼び出されてい サーバーメソッドの結果がクライアントに返されます。

Meteorには、私が言ったことを無効にするもう1つの微妙な機能があります:レイテンシ補正とメソッドスタブ。 サーバーメソッド呼び出しをクライアントで適切にシミュレートして、サーバーへのラウンドトリップなしですぐに実行できる場合は、メソッドスタブ(またはシミュレーション)と呼ばれるものを定義できます。

この動作の一般的な使用例は、(ブログ記事の下のコメントなどの)投稿されたユーザーコンテンツのローカル(クライアント側の複製サブセット)データベースへの即時挿入です。サーバー側の挿入をシミュレートするのは理にかなっています。 次に、サーバーがこれらの変更をまだ承認していなくても、コンテンツを提出するとすぐにユーザーがWebページを更新したと見なします。 (これはMeteorでレイテンシ補正がどのように実装されているかの例です)。

もちろん、サーバーには最終的にデータベースに挿入されるものに関する最終的な単語があります。つまり、サーバー側のツインメソッドが実行されると、そのアクションが優先され、ローカルデータベースに挿入されたものが置き換えられます。

このようなメソッドスタブを定義するには、クライアントコードに同じサーバーメソッド名を定義するだけです。 メソッド宣言が共有コード(クライアントとサーバの両方に同梱)で定義されている場合、メソッド呼び出しは、実際にisSimulationプロパティをチェックして、シミュレーションであれば、あなたがテストすることができます。

Meteor.methods({ 
    myMethod: function(arguments...){ 
     if(this.isSimulation){ 
      // called from the client 
     } 
    } 
}); 

UPDATE 26/11/2014: @ steph643は私の前の答えの最後の部分が実際に間違っていた方法についてコメントしました、ここで修正があります。

サーバー環境では、適切なブロッキングメカニズム(ファイバー)が提供されるため、サーバー上ではメソッド呼び出しは常に同期構文を使用して呼び出すことができます。クライアントで

あなたはメソッドスタブから何かを返す場合は、あなたが別のスタブの中にいる場合にのみ、同期的に実行することができ、あなたが同期の方法で結果を取得することができ、すなわち

Meteor.methods({ 
    intermediateMethod: function(){ 
    return " WORLD"; 
    }, 
    method: function(){ 
    var result = "HELLO"; 
    result += intermediateResult; 
    var intermediateResult = Meteor.call("intermediateMethod"); 
    return result; 
    } 
}); 

この動作は、Mongoのコレクション操作(挿入/更新/削除)がMeteorメソッドとして実装されており、クライアントのバージョンが同期的に実行できる有効なスタブ(minimongo複製ローカルデータベースサブセットの変更)を実装していることを考えるとちょっと変わったものです。

+0

ありがとうございました。私の周りに頭を浮かべなければなりませんでしたが、これは多くの助けとなりました。 http://www.eventedmind.com/posts/meteor-methods – jaggy

+2

"メソッドスタブから何かを返すと、クライアント上で同期して実行でき、通常の方法で結果を取得できます"。本当じゃない。クライアントから発行されたメソッド呼び出しは、スタブがあるかどうかに関係なく、 'undefined'を返します。 Cf。 "クライアントでは、コールバックを渡さずにスタブ内にいない場合(つまり、別のスタブ内からメソッドを呼び出さないことを意味する)、コールは未定義に戻り、取得する方法はありませんメソッドの戻り値 "を返します。これは、スタブがメソッドにアタッチされているかどうかに関係なく適用されます。 – steph643

+0

これを指摘してくれてありがとう、私は流星核についてもあなたの話題に従っています。私は自分の答えでドキュメントを引用し、メソッドスタブのクライアント側の同期実行は他のメソッド呼び出し内でしか実行できないと明示的に述べていますが、それはほとんど意味がないので、 – saimeunt