2016-07-13 5 views
1

URLのスクリーンショットをとるNode.JSアプリケーションがあります。複数のユーザーが同時に同じURLを要求する可能性があるため、ある瞬間にURLのスクリーンショットを1回だけ取得するようにしたいと考えています。特定のパラメータの各タスクがNode.JSで1回だけ実行されることを確認する

私はそれを以下のように実装しました:私が疑問に思う何

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; 
} 

は、私はいくつかの並行性の問題や、これを実装するためのより良い方法を欠けているかどうか?

答えて

0

私の意見では、あなたが提供したコードは仕事をきれいにします。約束の非同期アクションは次の可能/利用可能チックに呼び出される前に

私はちょうどあなたが(満たす)決意をコールすると、別のコーナーケース:)

を最適化しようとしたの下

は、実行は、イベントループに入ります。イベントループで誰かが同じ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; 
} 
関連する問題