コレクションからランダムに2つをユーザーに表示するアプリを作っています。ユーザーがページを更新したりボタンをクリックしたりするたびに、別のランダムなアイテムのペアを取得します。
たとえば、コレクションが果物の場合、次のようなものが必要です。
リンゴvsバナナ
ピーチvsパイナップル
バナナvsピーチ
以下のコードはサーバー側用であり、ランダムペアが1回だけ生成されるという事実を除いて機能します。サーバーが再起動されるまで、ペアは更新されません。generate_pair()
一度だけ呼び出されるからだと思います。関数のgenerate_pair()
1つから呼び出してみましたが、Meteor.publish
たまにしか機能しません。また、アイテムがない(エラー)か、アイテムが1つしかない場合もあります。
コレクション全体を公開し、クライアント側からランダムなアイテムを選択してもかまいません。Items
30,000エントリある場合、ブラウザをクラッシュさせたくありません。
結論として、クライアント側に表示されるコレクションから2つのランダムなアイテムを取得する方法について誰かがアイデアを持っていますか?
var first_item, second_item;
// This is the best way I could find to get a random item from a Meteor collection
// Every item in Items has a 'random_number' field with a randomly generated number between 0 and 1
var random_item = function() {
return Items.find({
random_number: {
$gt: Math.random()
}
}, {
limit: 1
});
};
// Generates a pair of items and ensure that they're not duplicates.
var generate_pair = function() {
first_item = random_item();
second_item = random_item();
// Regenerate second item if it is a duplicate
while (first_item.fetch()[0]._id === second_item.fetch()[0]._id) {
second_item = random_item();
}
};
generate_pair();
Meteor.publish('first_item', function() {
return first_item;
});
// Is this good Meteor style to have two publications doing essentially the same thing?
Meteor.publish('second_item', function() {
return second_item;
});
あなたのアプローチの問題は、同じ引数(この場合は引数なし)で同じパブリケーションをクライアントで何度もサブスクライブすると、サーバー側ロジックに1回だけサブスクライブされることです。これは、Meteorがその最適化を行っているためです。内部Pub / Subメカニズム。
以前のサブスクリプションを本当に破棄し、サーバー側の公開コードで2つの新しいランダムなドキュメントを再実行して送信するには、パブリケーションに役に立たないランダムな引数を導入する必要があります。クライアント側のコードは、パブリケーションに何度もサブスクライブします。乱数を使用して、購読を解除し、新しいランダムドキュメントを再購読するたびに。
このパターンの完全な実装は次のとおりです。
server/server.js
function randomItemId(){
// get the total items count of the collection
var itemsCount = Items.find().count();
// get a random number (N) between [0 , itemsCount - 1]
var random = Math.floor(Random.fraction() * itemsCount);
// choose a random item by skipping N items
var item = Items.findOne({},{
skip: random
});
return item && item._id;
}
function generateItemIdPair(){
// return an array of 2 random items ids
var result = [
randomItemId(),
randomItemId()
];
//
while(result[0] == result[1]){
result[1] = randomItemId();
}
//
return result;
}
Meteor.publish("randomItems",function(random){
var pair = generateItemIdPair();
// publish the 2 items whose ids are in the random pair
return Items.find({
_id: {
$in: pair
}
});
});
client/client.js
// every 5 seconds subscribe to 2 new random items
Meteor.setInterval(function(){
Meteor.subscribe("randomItems", Random.fraction(), function(){
console.log("fetched these random items :", Items.find().fetch());
});
}, 5000);
meteor add random
このコードが機能するために必要です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加