【问题标题】:Making sure each task for a given parameter is done only once in Node.JS确保给定参数的每个任务在 Node.JS 中只执行一次
【发布时间】:2016-07-13 10:16:17
【问题描述】:

我有一个对 URL 进行屏幕截图的 Node.JS 应用程序。因为多个用户可能同时请求同一个 URL,所以我想确保在任何给定时刻我只抓取一次 URL 的屏幕截图。

我通过以下方式实现了它:

var inProgressUrls = {};

function grabScreenshot(url) {
  var inProgress = inProgressUrls[url];
  if (inProgress) {
    return inProgress;
  }

  var promise = new Promise(function(fulfill, reject) {
    ... grab screenshot ...

    // Once done, remove the Promise from the map.
    delete inProgressUrls[url];
  });

  inProgressUrls[url] = promise;

  return promise;
}

我想知道的是我是否遗漏了一些并发问题或更好的实现方法?

【问题讨论】:

    标签: javascript node.js concurrency promise


    【解决方案1】:

    在我看来,您提供的代码很干净。

    下面我只是尝试优化另一个极端情况:)

    调用 resolve(fulfill) 后,执行将进入事件循环,然后在下一个可用/可能的滴答中调用 Promise 的异步操作。假设在 eventloop 中有人用相同的 url 调用 grabScreenshot,我试图在下面优化它。

    delete 将发生在异步操作中,除了来自对象的delete url 之外什么都不做。

    var inProgressUrls = {};
    
    function grabScreenshot(url) {
        var inProgress = inProgressUrls[url];
        if (inProgress) {
            return inProgress;
        }
    
        var promise = new Promise(function(fulfill, reject) {
            asyncScreenGrab(url,(error, data) => {
                if (!error) {
                    fulfill(data);
                } else {
                    reject(error);
                }
    
                //NOT CALLING DELETE HERE TO OPTIMISE LITTLE MORE!
                //IF GRAB IS CALLED WITH SAME URL WHILE AFTER THE RESOLVE OR REJECT, BUT WE ARE AT EVENT LOOP
                //AND ASYN ACTIONS ARE NOT STARTED EXECUTING
            });
        });
    
        inProgressUrls[url] = promise;
    
        //DELETE THE STORED PROMISE EITHER FOR RESOLVE OR FOR REJECT
        promise.then(() => delete inProgressUrls[url]).catch(() => delete inProgressUrls[url])
    
        return promise;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多