【发布时间】:2016-05-07 19:48:17
【问题描述】:
我正在尝试同步获取 mongodb 实例。我知道不建议这样做,但我只是尝试并想知道为什么这不起作用。 this.db 在等待 10 秒后仍然未定义,而通常异步代码在不到 500 毫秒的时间内获得它。
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 是单线程的,根据定义,busy-loop 的存在会阻止设置值。如果 JS 一直在循环,它就没有机会分配
db。您最好将这个问题改写为“我应该如何重写这段代码才能正常工作”。 -
我认为问题应该至少部分地在问题的标题中表现出来。
This code要求读者查看问题的正文。 -
简而言之,您不能从同步函数返回异步值。你根本无法做到这一点。您繁忙的等待循环不会像 Javascript 那样运行。因为您永远不允许事件循环处理下一个事件,所以您的数据库完成回调将永远不会被调用。您必须为异步结果编程。返回一个承诺或传入一个回调。
-
可能应该只是阅读这个How do I return a value from an asynchronous function。那里涵盖了所有设计选项。
标签: node.js mongodb async-await babeljs