简体   繁体   English

如果已经完成类似的工作,则延迟Node.js HTTP请求

[英]Defer Node.js HTTP requests if similar work already being done

I'm making a service which retrieves a photograph from a remote host and does some processing before passing it on to the client. 我正在提供一项服务,该服务将从远程主机检索照片并进行一些处理,然后再将其传递给客户端。 It caches the retrieved source photo locally to avoid retrieving it again later on. 它在本地缓存检索到的源照片,以避免以后再次检索它。

However, if there are several requests in rapid succession, the source image will not yet have been saved locally, and unnecessary retrievals are performed. 但是,如果快速连续有多个请求,则源图像将尚未保存在本地,并且将执行不必要的检索。

What is a nice approach to defer the incoming requests until the source image is cached, provided it's already currently being retrieved? 如果当前已检索到源映像,有什么好方法可以将传入请求推迟到缓存源映像之前呢?

I'm currently using Node.js streams all the way from the inbound request stream, passing it through my caching and transformation logic, passing it to the outbound stream. 我当前正在从入站请求流一直使用Node.js流,将其通过我的缓存和转换逻辑传递,然后将其传递到出站流。

You can cache the promise so all incoming requests to the same resource will only require one trip, avoiding flooding the database or some API. 您可以缓存promise,这样对同一资源的所有传入请求都只需要进行一次旅行,从而避免了数据库或某些API的泛滥。

const Cache = {};

function getPhoto(photoId) {

    let cacheKey = `photo-${photoId}`;
    let photoCache = Cache[cacheKey];

    if (photoCache instanceof Promise)
        return photoCache; //Return the promise from the cache

    let promise = new Promise((resolve, reject) => {

        if (photoCache) //Return the photo if exists in cache.
            return resolve(photoCache);

        return processPhoto(photoId).then(response => {
            //Override the promise with the actual response
            Cache[cacheKey] = response; 
            resolve(response);

        }).catch(err => { 
            Cache[cacheKey] = null; //We don't want the rejected promise in cache!
            reject();
        });

    });

    if (!photoCache)
        Cache[cacheKey] = promise; //Save the promise       

    return promise;
}

function processPhoto(photoId){

 return new Promise((resolve, reject) => {

      // Get the image from somewhere...
      // Process it or whatever you need

      //...
      resolve('someResponse');
 });

}
  • First request to a specific photo will perform the lookup, and will store the promise in the cache. 对特定照片的第一个请求将执行查找,并将promise存储在缓存中。
  • Second request comes in and if the photo from first request hasn't yet been retrieved, getPhoto will return the same promise, when the promise is resolved, both requests will get the same response. 第二个请求进入,如果尚未检索到第一个请求的照片,则getPhoto将返回相同的承诺,当解决承诺后,两个请求将获得相同的响应。
  • Third request comes after the photo has been already retrieved, since the photo is cached it will just return the response. 在已检索到照片之后,将发出第三个请求,因为照片已被缓存,它将仅返回响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM