elasticsearch,event-loop,Javascript,Node.js,elasticsearch,Event Loop" /> elasticsearch,event-loop,Javascript,Node.js,elasticsearch,Event Loop" />

General node.js/javascript问题和事件循环

General node.js/javascript问题和事件循环,javascript,node.js,elasticsearch,event-loop,Javascript,Node.js,elasticsearch,Event Loop,我有以下问题: 我让两个函数写入我的数据库。在将它们插入数据库之前,我会检查是否存在类似的项: const storeListing = async listing => { //Some logic const foundSimilar = await findSimilar(listing); if(!foundSimilar){ await insertListing(listing) }else{ //Perform duplicate che

我有以下问题: 我让两个函数写入我的数据库。在将它们插入数据库之前,我会检查是否存在类似的项:

const storeListing = async listing => {
   //Some logic
   const foundSimilar = await findSimilar(listing);
  if(!foundSimilar){
     await insertListing(listing)
  }else{
    //Perform duplicate check
    if(foundSimilar.buildingType===listing.buildingType){
       console.log('found')
    }
  }
}
现在,当我做以下工作时:

const test = () => {
  storeListing({buildingType:'MFH'});
  storeListing({buildingType:'MFH'});
}
带有重复检查的else条件永远不会触发

我的想法是这两个函数按顺序处理(事件循环)。因此,在完成一个操作之前,不能再次调用storeListing

那么,我在这里是否有一个逻辑问题,或者仅仅是数据库具有最终的一致性


编辑: 当我不知道有多少其他函数调用storeListing并且我希望它序列化时(例如,我有多户住宅的storeListing-单户住宅的storeListing)

这是一个好的模式:

const lock={};
export const storeListing = async (listing, type) => {
  const id= uuidv1();

  while (Object.keys(lock).length>0){
    await timeout(15);
  }
  threadLock[id]=true;
  //Function like above

  delete lock[id];
}

即使插入顺序不相关,您仍然需要使用
wait
,以避免竞争条件

完整代码将以下I/O操作排入队列:

  • 芬德西拉隆
  • insertListingOne(如果findSimilarOne返回不匹配)
  • 找到相似的两个
  • insertListingTwo(如果findSimilarTwo返回不匹配)
  • 对这些操作顺序的唯一限制是#1必须出现在#2之前,而#3必须出现在#4之前

    完成这些任务的顺序是:#1、#3、#2、#4

    因为这两个
    findSimilar
    调用都在其中一个
    insertListing
    完成之前完成,所以它们都不返回匹配项

    您应该使用
    async
    ,如下所示:

    let test = async () => {
      await storeListing({ buildingType:'MFH' });
      await storeListing({ buildingType:'MFH' });
    };
    

    这对操作顺序实施了一个新的限制:在测试中,2必须出现在3之前。您的not
    WAIT
    ing。在这种情况下,顺序无关紧要-项目类似。因此,如果插入一个,则第二个将类似,反之亦然。我只是在这里发表了一条评论——这里仍然有逻辑,但为了更好地概述,将其省略了;)但我现在让代码更清楚了:)这看起来像是一个数据库竞争条件,因为您同时有两个查询,它们不会被序列化。当您调用本机代码接口(如数据库)时,本机代码上可能没有任何单线程、事件循环驱动的限制。无法以这种方式编程到本机代码接口。您必须向我们展示
    findSimilar()
    的实际代码,以便我们了解建议内容,但您通常需要了解数据库的并发管理功能。仅供参考,发布一个仅包含伪代码的问题意味着我们无法给您任何具体建议,只能提供伪建议。这里的正确解决方案取决于实际的代码、使用的数据存储类型及其接口。在这里提问时,请张贴真实代码。您将得到更多更有价值的建议,而且通常会更快,而不会有太多来回的问题。这通常是解决数据库并发性问题的错误方法。对于这样的问题,数据库具有内置的并发特性,而这些问题没有像这样的所有限制。另外,在事件驱动系统中轮询锁是一种非常糟糕的设计。你会有一堆锁处于挂起和活动状态,你的CPU会花很多时间轮询锁。更不用说,你没有一个“公平”的系统来决定谁下一个去,因为这是随机的。无法使用群集。无法防止其他进程访问数据库等等……或者可能
    storeListing
    被认为可以正确执行事务,而bug就在那里。从这个问题上我不清楚要求是什么。这可能是一个更好的建议!我更喜欢在DB层看到“buildingType”(或任何构成“相似性”的东西)的唯一性。是的,我发现我的问题不够尖锐。对此我很抱歉。但所有这些建议都对我有所帮助