这是我所拥有的功能:
let counter = 0;
let dbConnected = false;
async function notASingleton(params) {
if (!dbConnected) {
await new Promise(resolve => {
if (Math.random() > 0.75) throw new Error();
setTimeout((params) => {
dbConnected = true; // assume we use params to connect to DB
resolve();
},1000);
});
return counter++
}
};
// in another module that imports notASingleton
Promise.all([notASingleton(params),notASingleton(params),notASingleton(params)]);
或
// in another module that imports notASingleton
notASingleton(params);
notASingleton(params);
notASingleton(params);
notASingleton(params);
问题在于,显然notASinglton
in中的诺言可能是同时执行的,并且假设它们并行运行,那么所有承诺的执行上下文都是dbConnected = false
。
注意:我知道我们可以引入一个新变量,例如initiatingDbConnection
,而不是检查!dbConnected
,而是检查!initiatingDbConnection
;但是,只要并发意味着在Promise.all
内部,承诺的上下文将是相同的,那将不会有任何改变。
该模式可以在例如通过利用JVM的约定创建类的Java:https://stackoverflow.com/a/16106598/12144949
但是,即使Java实现也不能用于需要传递变量的用例:“客户端应用程序无法传递任何参数,因此我们无法重用它。例如,具有通用单例客户端应用程序提供数据库服务器属性的数据库连接类。” https://www.journaldev.com/171/thread-safety-in-java-singleton-classes-with-example-code
注2:另一个可能相关的问题:https://eslint.org/docs/rules/require-atomic-updates#rule-details