私はmongodbインスタンスを同期的に取得しようとしています。私はこれが推奨されていないことを知っているが、私はちょうど実験し、なぜこれが動作しないのだろうかと思うthis.db
は、通常非同期コードが500ミリ秒未満でそれを取得した場合、10秒後には未定義です。非同期的に待機することで値を取得できないのはなぜですか?
Repository.js:
var mongodb = require('mongodb');
var config = require('../config/config');
var mongoConfig = config.mongodb;
var mongoClient = mongodb.MongoClient;
class Repository {
constructor() {
(async() => {
this.db = await mongoClient.connect(mongoConfig.host);
})();
}
_getDb(t) {
t = t || 500;
if(!this.db && t < 10000) {
sleep(t);
t += 500;
this._getDb(t);
} else {
return this.db;
}
}
collection(collectionName) {
return this._getDb().collection(collectionName);
}
}
function sleep(ms) {
console.log('sleeping for ' + ms + ' ms');
var t = new Date().getTime();
while (t + ms >= new Date().getTime()) {}
}
module.exports = Repository;
app.js:
require('../babelize');
var Repository = require('../lib/Repository');
var collection = new Repository().collection('products');
JSはシングルスレッドで、定義により、あなたの忙しいループの存在が設定されることから値を防ぐことができます。 JSが時間を費やしている場合、 'db'を割り当てる機会はありません。この質問を「このコードを書き直すにはどうすればよいのですか」と言い換えればよいでしょう。 – loganfsmyth
私は、問題が少なくとも部分的に問題のタイトルに再提示されるべきだと思います。 「このコード」は、読者が質問の本文を覗くことを要求する。 – jstice4all
一言で言えば、同期関数から非同期の値を返すことはできません。あなたは単にそれをすることはできません。あなたのビジー・ウェイト・ループは、Javascriptが動作する方法では動作しません。イベントループが次のイベントを処理することを許可しないため、データベース完了コールバックは決して呼び出されません。あなたは非同期の結果のためにプログラムしなければなりません。約束を返すか、コールバックを渡す。 – jfriend00