2016-07-13 10 views
1

Ich habe eine Node.JS-Anwendung, die einen Screenshot einer URL erstellt. Da mehrere Benutzer möglicherweise dieselbe URL zur gleichen Zeit anfordern, möchte ich sicherstellen, dass ich zu jedem beliebigen Zeitpunkt nur einmal einen Screenshot einer URL abrufe.Stellen Sie sicher, dass jede Aufgabe für einen bestimmten Parameter nur einmal in Node.JS

Ich habe es die folgende Art und Weise umgesetzt:

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

Was ich frage mich, ob ich ein paar Concurrency Probleme oder eine bessere Art und Weise bin fehlt, dies zu implementieren?

Antwort

0

Meiner Meinung nach macht der von Ihnen bereitgestellte Code den Job sauber.

unten habe ich versucht, einfach eine andere Ecke Fall zu optimieren :)

Sobald Sie Entschlossenheit nennen (erfüllen), geht die Ausführung zu Ereignisschleife, bevor die Asynchron-Aktionen von Versprechen in der nächsten verfügbar/möglich tick aufgerufen wird. Sagen wir, während jemand in Eventloop grabScreenshot mit derselben URL ruft, habe ich versucht, dies unten zu optimieren.

delete wird in async Aktion passieren, die nichts als delete url von Objekt tut.

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