gpt4 book ai didi

javascript 回调在不可能的调用中被调用两次

转载 作者:行者123 更新时间:2023-12-01 00:56:38 25 4
gpt4 key购买 nike

我构建了一个 TS,MongoDB 客户端包装器。由于某种原因,当我调用获取连接的函数时,它的回调被调用两次。

总共有 2 次对 get() 函数的调用,如您所见,一次在导出之前,另一次来自 Mocha 测试。

总的来说,我对 TS 和 JS 还很陌生,但这似乎有点不对劲。

    import {Db, MongoClient} from "mongodb";
import {MongoConfig} from '../config/config'
class DbClient {
private cachedDb : Db = null;
private async connectToDatabase() {
console.log('=> connect to database');
let connectionString : string = "mongodb://" + MongoConfig.host + ":" + MongoConfig.port;
return MongoClient.connect(connectionString)
.then(db => {
console.log('=> connected to database');
this.cachedDb = db.db(MongoConfig.database);
return this.cachedDb;
});
}
public async get() {
if (this.cachedDb) {
console.log('=> using cached database instance');
return Promise.resolve(this.cachedDb);
}else{
return this.connectToDatabase();
}
}
}
let client = new DbClient();
client.get();
export = client;

控制台输出是:

=> connect to database
=> connected to database
=> connected to database

这种行为不当有什么具体原因吗?

最佳答案

There are 2 calls in total to the get() function, 1 before the export as you can see and another from a mocha test.

我怀疑输出有一个额外的=>连接到数据库。正如我在评论中所说:有一个“竞争条件”,在设置 this.cachedDb 之前可以多次调用 get() ,这将导致多个连接/实例正在创建的数据库的数量。

例如:

const a = client.get();
const b = client.get();

// then
a.then(resultA => {
b.then(resultB => {
console.log(resultA !== resultB); // true
});
});

解决方案

可以通过将 Promise 存储为缓存值来解决这个问题(而且,正如 Randy 指出的那样,不需要在方法上使用 async 关键字,因为在任何方法中都没有等待值)方法,这样你就可以返回 promise ):

import {Db, MongoClient} from "mongodb";
import {MongoConfig} from '../config/config'

class DbClient {
private cachedGet: Promise<Db> | undefined;

private connectToDatabase() {
console.log('=> connect to database');
const connectionString = `mongodb://${MongoConfig.host}:${MongoConfig.port}`;
return MongoClient.connect(connectionString);
}

get() {
if (!this.cachedGet) {
this.cachedGet = this.connectToDatabase();

// clear the cached promise on failure so that if a caller
// calls this again, it will try to reconnect
this.cachedGet.catch(() => {
this.cachedGet = undefined;
});
}

return this.cachedGet;
}
}

let client = new DbClient();
client.get();
export = client;

注意:我不确定使用 MongoDB 的最佳方式(我从未使用过它),但我怀疑连接不应该太长,以至于像这样缓存(或者应该只缓存短时间后断开连接)。不过,您需要对此进行调查。

关于javascript 回调在不可能的调用中被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56527492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com