Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 为什么我不能通过同步等待从异步等待中获取值?_Node.js_Mongodb_Async Await_Babeljs - Fatal编程技术网

Node.js 为什么我不能通过同步等待从异步等待中获取值?

Node.js 为什么我不能通过同步等待从异步等待中获取值?,node.js,mongodb,async-await,babeljs,Node.js,Mongodb,Async Await,Babeljs,我正在尝试同步获取mongodb实例。我知道这是不推荐的,但我只是试验,不知道为什么这不起作用this.db在等待10秒后仍然未定义,而通常异步代码在不到500毫秒的时间内获取它 Repository.js: var mongodb = require('mongodb'); var config = require('../config/config'); var mongoConfig = config.mongodb; var mongoClient = mongodb.MongoCli

我正在尝试同步获取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;

Javascript是一种基于事件的体系结构。所有代码都是通过事件队列中的一个事件启动的,只有在前一个事件中的代码完成执行后,才会从事件队列中提取下一个事件。这意味着您的主Javascript代码是单线程的

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

现在来看看你的代码。您开始运行一些启动异步操作的代码。然后,您将永远循环,永远不会返回系统。因此,异步操作完成后事件队列中的下一个事件永远无法运行

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

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


您可以在这里看到异步编码选项:

Javascript是一种基于事件的体系结构。所有代码都是通过事件队列中的一个事件启动的,只有在前一个事件中的代码完成执行后,才会从事件队列中提取下一个事件。这意味着您的主Javascript代码是单线程的

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

现在来看看你的代码。您开始运行一些启动异步操作的代码。然后,您将永远循环,永远不会返回系统。因此,异步操作完成后事件队列中的下一个事件永远无法运行

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

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


您可以在这里看到异步编码选项:

JS是单线程的,根据定义,存在繁忙循环会阻止设置该值。如果JS花费整个时间循环,它就没有机会分配
db
。你最好将这个问题重新表述为“我应该如何重写代码使其工作”。我认为这个问题应该在问题的标题中至少部分地重新表述<代码>此代码要求读者仔细查看问题的主体。简而言之,您不能从同步函数返回异步值。你根本不能那样做。您的忙等待循环无法以Javascript运行的方式工作。由于从不允许事件循环处理下一个事件,因此将永远不会调用数据库完成回调。您必须为异步结果编程。返回一个承诺或在回调中传递。可能应该阅读此内容。这里介绍了所有的设计选项。JS是单线程的,根据定义,繁忙循环的存在会阻止设置该值。如果JS花费整个时间循环,它就没有机会分配
db
。你最好将这个问题重新表述为“我应该如何重写代码使其工作”。我认为这个问题应该在问题的标题中至少部分地重新表述<代码>此代码要求读者仔细查看问题的主体。简而言之,您不能从同步函数返回异步值。你根本不能那样做。您的忙等待循环无法以Javascript运行的方式工作。由于从不允许事件循环处理下一个事件,因此将永远不会调用数据库完成回调。您必须为异步结果编程。返回一个承诺或在回调中传递。可能应该阅读此内容。这里介绍了所有的设计选项。
require('../babelize');

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