为什么我无法通过同步等待从异步等待中获取值



我正在尝试同步获取mongodb实例。 我知道不建议这样做,但我只是尝试并想知道为什么这不起作用。 this.db在等待 10 秒后仍未定义,而通常异步代码在不到 500 毫秒的时间内即可获得它。

存储库.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;

应用.js:

require('../babelize');
var Repository = require('../lib/Repository');
var collection = new Repository().collection('products');

Javascript是一个基于事件的架构。 所有代码都通过事件队列中的事件启动,并且仅当上一个事件中的代码完成执行时,才会从事件队列中提取下一个事件。 这意味着您的主要 Javascript 代码是单线程的。

因此,当您触发异步操作时,它会启动一个操作,当该操作完成后,它会将事件放入事件队列中。 该事件(将触发异步操作的回调(将不会运行,直到上一个事件中的代码完成运行并返回到系统。

所以,现在进入你的代码。 您开始运行一些启动异步操作的代码。 然后,你永远循环,永远不会回到系统。 因此,从异步操作完成开始的事件队列中的下一个事件永远不会运行。

因此,简而言之,您不能在循环中旋转等待异步操作完成。 这与Javascript使用的事件驱动方案不兼容。 您永远不会返回到事件系统以让异步完成回调运行。 所以,你只有一个死锁或无限循环。

相反,您需要通过返回承诺或传入稍后调用的回调来为异步响应编写代码。 你的代码需要完成执行,然后让回调在将来的某个时候被调用。 在 Javascript 中没有循环旋转等待其他东西运行。

您可以在此处查看异步编码选项:如何从异步调用返回响应?

最新更新