Javascript 如何防止在写入文件时访问该文件,并在写入文件后恢复执行?

Javascript 如何防止在写入文件时访问该文件,并在写入文件后恢复执行?,javascript,node.js,concurrency,Javascript,Node.js,Concurrency,当服务器收到请求时,我运行函数foo。在foo期间的某个时刻,我检查我的机器上是否存在某些文件(基于请求),并远程获取那些不存在的文件,将它们保存在本地以备将来请求时使用 如果我同时收到多个请求,而这两个请求都引用了服务器上不存在的相同文件bar,我就会遇到问题。以下是发生的事件的时间线示例: 请求1异步检查是否存在bar 请求2异步检查是否存在bar 请求1发现bar不存在,因此它异步下载文件 请求2发现bar不存在,因此它异步下载文件 请求1打开一个到bar的写入流,并异步地将文件响应导入该

当服务器收到请求时,我运行函数
foo
。在
foo
期间的某个时刻,我检查我的机器上是否存在某些文件(基于请求),并远程获取那些不存在的文件,将它们保存在本地以备将来请求时使用

如果我同时收到多个请求,而这两个请求都引用了服务器上不存在的相同文件
bar
,我就会遇到问题。以下是发生的事件的时间线示例:

  • 请求1异步检查是否存在
    bar
  • 请求2异步检查是否存在
    bar
  • 请求1发现
    bar
    不存在,因此它异步下载文件
  • 请求2发现
    bar
    不存在,因此它异步下载文件
  • 请求1打开一个到
    bar
    的写入流,并异步地将文件响应导入该写入流
  • 请求2打开一个到
    bar
    的写入流,并异步地将文件响应导入该写入流
  • 请求1完成文件写入,尝试使用图像加载库加载其内容(图像),最终抛出错误
  • 发生这种情况的原因是文件内容无效,因为文件正在被请求2覆盖

    我知道解决这个问题可能会涉及文件锁定,因此第一个发现文件在本地丢失的请求可以创建一个lockfile,以向后续请求指示该文件已经被提取/写入。我不确定的是如何让这些后续请求等待文件加载完成

    我是否应该使用生成器函数,并在看到其他请求正在获取此远程文件时暂停函数的执行?那样的话,我以后怎么恢复呢?我是否必须维护暂停请求的全局队列


    是否有任何资源可以帮助我更好地理解这里要做什么?

    您需要某种形式的同步。只要运行一个NodeJS进程,最简单的方法就是使用JavaScripts单线程行为:

      const fileLoading = new Map();
    
      async function getFile(id) {
        if(fileLoading.has(id)) {
          await fileLoading.get(id);
        } else {
         const load = (async function() {
            await fetchFile(id);
            fileLoading.remove(id);
         })();
         fileLoading.set(id, load);
         await load;
       }
       return await readFile(id);
     }
    

    您将需要某种形式的同步。只要运行一个NodeJS进程,最简单的方法就是使用JavaScripts单线程行为:

      const fileLoading = new Map();
    
      async function getFile(id) {
        if(fileLoading.has(id)) {
          await fileLoading.get(id);
        } else {
         const load = (async function() {
            await fetchFile(id);
            fileLoading.remove(id);
         })();
         fileLoading.set(id, load);
         await load;
       }
       return await readFile(id);
     }
    

    这是一个单服务器问题,文件没有外部争用吗?或者这是一个多服务器问题和/或文件也存在外部争用。如果是单服务器问题,选项就简单多了。另外,请显示实际代码的相关部分,因为您如何检查文件是否存在(以防止争用条件)的详细信息也很重要。这是一个单服务器问题,对文件没有外部争用吗?或者这是一个多服务器问题和/或文件也存在外部争用。如果是单服务器问题,选项就简单多了。此外,请显示您实际拥有的任何代码的相关部分,因为您如何检查文件的存在(以防止竞争条件)的详细信息也很重要。