我有点像JS的纽比( newby ),我只是想知道,如果我计划从一堆不同的异步函数中向它写入数据,是否需要使一个对象相互排斥?为了给出一个更具体的例子,我试图从一些不同的网站中分析一些与体育赛事相关的数据,并希望在一个包含体育赛事一般信息的中心对象中写出与上述网站相关的具体信息,以及我从每个网站中提取的更具体的事件数据。理想情况下,所有这些操作都是相互异步的,以提高性能。
提前感谢!
发布于 2022-05-24 03:43:42
Nodejs在一个线程中运行Javascript。因此,您的Javascript中的两段将不会在完全同时运行。因此,您将不会对Javascript的两段内容产生问题,它们都试图以类似多线程C++代码的方式同时访问对象。无论Javascript的源是什么,无论它是否在async
函数中,这都是正确的。
即使您使用WorkerThreads,它们也不提供对相同变量的同时访问(每个WorkerThread都有自己的变量空间),您将通过消息传递传递值更改,消息通过事件循环运行,从而协调对其他代码的访问。在WorkerThreads的最低级别,有一种SharedArrayBuffer
数据类型确实允许线程之间的访问,您必须使用原子学或类似的东西来保护您的访问。但是,这是一个非常具体的情况和非常具体的数据类型。
尽管如此,在Javascript中仍然可以使用一些非常简单的方法,比如,如果您在代码中有一些共享资源(由代码的其他部分访问的资源),那么每当您在代码中碰到await
或.then()
回调时,解释器返回到promiseQueue或事件循环,然后在等待解析/拒绝的承诺时运行其他代码。如果其他代码也可以修改这个共享资源,这对于第一个代码来说是个问题,那么您可能会有一个争用条件。
所以,如果你就这么做:
let someValue = someSharedObj.prop;
let delta = await someFunction();
someSharedObj.prop = someValue + delta;
您必须知道,当您在someSharedObj
时,其他代码可能会访问await
,这可能是一种竞争条件,在这种情况下,该代码可能会覆盖其他代码在await
中所做的更改。可将其改写如下:
let delta = await someFunction();
let someValue = someSharedObj.prop;
someSharedObj.prop = someValue + delta;
并且竞争条件不再存在,因为它在获得支柱、向其添加值并将其写回之间是完全同步的代码。没有其他Javascript可以在最后两条语句之间运行。如果其他代码碰巧在await
期间运行,这不会导致更新someSharedObj
的问题。
就如何避免这些问题提出一般性建议有点困难。对于数据库,数据库通常具有原子操作,您可以使用这些操作来避免竞争条件、事务或锁。例如,大多数数据库都有一种原子方式来递增或递减一个值,而不必异步获取值、增量并异步地将其写回(这很容易受到竞争条件的影响)。
对于您自己的共享数据,避免竞争条件通常包括不通过await
或.then()
回调保存数据。
https://stackoverflow.com/questions/72356123
复制相似问题