sql >> データベース >  >> NoSQL >> MongoDB

MeteorとFibers/bindEnvironment()はどうなっていますか?

    bindEnvironmentを少し間違って使用しています。使用されている場所がすでにファイバー内にあり、Knoxクライアントからのコールバックがファイバー内にないためです。

    bindEnvironmentには2つのユースケースがあります(私が考えることができる、もっとあるかもしれません!):

    • 変更する必要のあるグローバル変数がありますが、他のユーザーのセッションに影響を与えたくない

    • サードパーティのapi/npmモジュールを使用してコールバックを管理しています(これが当てはまるようです)

    Meteor.bindEnvironment 新しいファイバーを作成し、現在のファイバーの変数と環境を新しいファイバーにコピーします。これが必要なのは、nomモジュールのメソッドコールバックを使用するときです。

    幸いなことに、あなたを待っているコールバックを処理し、Meteor.wrapAsyncと呼ばれるファイバーでコールバックをバインドする代替手段があります 。

    だからあなたはこれを行うことができます:

    スタートアップ関数にはすでにファイバーがあり、コールバックがないため、ここでbindEnvironmentは必要ありません。

    Meteor.startup(function () {
       if (Projects.find().count() === 0) {
         insertRecords();
       }
    });
    

    また、レコードの挿入機能(wrapAsyncを使用)なので、コールバックは必要ありません

    function insertRecords() {
      console.log("inserting...");
      var client = Knox.createClient({
        key: apikey,
        secret: secret,
        bucket: 'profile-testing'
      });
          
      client.listSync = Meteor.wrapAsync(client.list.bind(client));
    
      console.log("created client");
          
      try {
          var data = client.listSync({ prefix: 'projects' });
      }
      catch(e) {
          console.log(e);
      }    
    
      if(!data) return;
    
    
      for (var i = 1; i < data.Contents.length; i++)  {
        console.log(data.Contents[i].Key);
        if (data.Contents[i].Key.split('/').pop() == "") {
          Projects.insert({ name: data.Contents[i].Key, contents: [] });
        } else if (data.Contents[i].Key.split('.').pop() == "jpg") {
          Projects.update( { name: data.Contents[i].Key.substr(0,
                             data.Contents[i].Key.lastIndexOf('.')) },
                           { $push: {contents: data.Contents[i].Key}} );
        } else {
          console.log(data.Contents[i].Key.split('.').pop());
        }
      }      
    });
    

    覚えておくべきことがいくつかあります。繊維は糸のようなものではありません。 NodeJSにはスレッドが1つだけあります。

    ファイバーは、同時に実行できるイベントのようなものですが、待機タイプのシナリオ(インターネットからのファイルのダウンロードなど)がある場合は、互いにブロックすることはありません。

    したがって、同期コードを使用して、他のユーザーのイベントをブロックすることはできません。それらは順番に実行されますが、それでも単一のスレッドで実行されます。つまり、これがMeteorがサーバー側に同期コードを持っている方法であり、それは何かを待つことができますが、他のユーザーはこれによってブロックされることはなく、コードが別のファイバーで実行されるため、何かを行うことができます。

    Chris Matherは、http://eventedmind.com

    にこれに関するいくつかの優れた記事を掲載しています。

    Meteor.wrapAsyncは何をしますか?

    Meteor.wrapAsync 最初のパラメーターとして指定したメソッドを受け取り、現在のファイバーで実行します。

    また、コールバックをアタッチします(最初のパラメーターがエラーで、2番目のパラメーターがfunction(err,result)などの結果である、コールバックを持つ最後のパラメーターをメソッドが受け取ることを前提としています。 。

    コールバックはMeteor.bindEnvironmentでバインドされています コールバックが発生するまで、現在のファイバーをブロックします。コールバックが起動するとすぐに、resultが返されます またはerrをスローします 。

    したがって、コールバックを使用してより深い関数をネストする代わりに、次の行でメソッドの結果を使用できるため、非同期コードを同期コードに変換するのに非常に便利です。また、bindEnvironmentも処理するため、ファイバーのスコープを失うことを心配する必要はありません。

    更新 Meteor._wrapAsync Meteor.wrapAsyncになりました 文書化されています。




    1. ネストされた配列を更新するための位置`$`演算子の複数の使用

    2. Mongodbアグリゲーション$group、配列の長さを制限

    3. RedisとMemcacheまたは単にRedis?

    4. MongoDBがシェルでデータベースを作成しない