这是我所拥有的功能:
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), notASingleton(params)]);
或
// in another module that imports notASingleton
notASingleton(params);
notASingleton(params);
notASingleton(params);
notASingleton(params);
问题是,notASinglton
中的Promise.all
承诺显然可以根据系统同时执行:“在某些计算机上,它们可以并行执行,或者在某种意义上可以同时执行,而在其他计算机上,它们可以执行。连续。”:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
假设它们并行运行,所有它们的执行上下文将为dbConnected = false
;我误读了MDN的说明吗?
注意:我知道我们可以引入一个新变量,例如initiatingDbConnection
,而不是检查!dbConnected
,而是检查!initiatingDbConnection
;但是,只要并发意味着在Promise.all
内部,承诺的上下文将是相同的,那将不会有任何改变。
该模式可以在例如Java通过利用JVM的约定创建类:https://stackoverflow.com/a/16106598/12144949
但是,即使Java实现也不能用于需要传递变量的用例:“客户端应用程序无法传递任何参数,因此我们无法重用它。例如,具有通用的singleton类用于客户端应用程序提供数据库服务器属性的数据库连接。”https://www.journaldev.com/171/thread-safety-in-java-singleton-classes-with-example-code
“在某些计算机上,它们可以并行执行,或者在某种意义上可以同时执行,而在其他计算机上,它们可以串行执行。”
该MDN描述是垃圾。我将其删除。 Promise.all
不负责执行任何操作,并且无论如何都不能“执行” promise。它所做的就是等待其参数,您就是在数组中创建这些承诺的人。即使您省略了Promise.all
并多次简单地调用notASingleton()
,它们也会运行(并同时打开多个连接)。
它们的执行上下文均为
dbConnected = false
是,但仅是因为您的dbConnected = true;
超时,并且您在此之前再次调用notASingleton()
。不是因为Promise.all
有什么特别之处。