我有一个Node.JS应用程序,它截取了一个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;
}
我想知道的是,我是否缺少一些并发问题或更好的实现方法?
答案 0 :(得分:0)
在我看来,您提供的代码可以帮助您完成工作。
下面我只是试图优化另一个角落案例:)
一旦调用resolve(fulfill),执行将进入事件循环,然后在下一个可用/可能的tick中调用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;
}