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
になりました 文書化されています。