用于缓存的Node.js同步请求

node.js synchronous requests for use in caching

本文关键字:同步 请求 js Node 缓存 用于      更新时间:2023-09-26

我有一个问题,我需要在我的代码中解决与缓存API结果有关。我有一些异步。像这样映射:

for(var user of allUsers) {
    var requestList = fill(cache, locations, apiUrl, cacheMap);
    async.map(requestList, function(obj, callback) {
        // ...
    }, function(err, results) {
        // PUT RESULTS INTO A CACHE
    });
}

函数fill只是在缓存中查看locations中的位置是否存在,而不是为我的API创建要运行的请求URL。

我意识到,然而,缓存不会有太多的使用与我的方法,因为我的代码将调度异步。map并立即开始下一个循环迭代fill,这意味着缓存不会在每次用户迭代时同步。

如何确保用户的每次迭代都有上次用户的更新版本的缓存?我需要非常明智地使用有限的API调用,所以如果有重复的请求,我想请求一次,然后在以后的请求中从缓存中提取结果。

我现在唯一的想法是发送一个同步请求而不是异步请求。

for(var user of allUsers) {
    var requestList = fill(cache, locations, apiUrl, cacheMap);
    // sync map instead
    requestList.map(function(obj) {
        var res = sync-request(obj)
        // put request result into cache
    });
    // cont...
}

您可以使用async.eachSeries迭代allUsers。这将按顺序执行并保持异步。

async.eachSeries(allUsers, (user, done) => {
  const requestList = fill(cache, locations, apiUrl, cacheMap);
  async.map(requestList, (obj, callback) => {
    // ..
    callback(null, requestResult);
  }, (err, results) => {
    // PUT RESULTS INTO A CACHE
    done(null, results);
  });
}, cb);

使用promise来代理和缓存API调用。批处理API请求和缓存结果使用promise非常简单。下面的一小段代码将一个现有的expensiveAPI调用封装在一个Promise中,并将解析后的结果缓存60秒。

// Existing module to call the expensive API
// using the standard callback pattern
var expensiveApi = require("./expensiveApi");
// Using bluebird promise library
// See http://bluebirdjs.com/docs/api-reference.html
var Promise = require("bluebird");
// Promisify the existing callback
expensiveApi = Promise.promisify(expensiveApi);
// Calls to the API will now return a Promise
// A cache for the Promises
var cache = {};
module.exports = function expensiveApiWithPromises(item) {
  // Check whether a cached Promise already exists
  if (cache[item]) {
    // Return it to the caller
    return cache[item];
  }
  // Promise is not in the cache
  cache[item] = expensiveApi(item)
  .then(function(result) {
    // Promise has resolved
    // set the result to expire
    setTimeout(function() {
      delete cache[item];
    }, 60 * 1000); // 60 seconds expiry
    // Return the result
    return result;
  })
  .catch(function(err) {
    // Promise rejected with an error
    // Reset the cache item
    delete cache[item];
    // Propagate the error
    throw err;
  });
  // Return the newly created cached Promise
  return cache[item];
}