这是运行良好的实际代码,仅向具有某些参数的api发送请求:
var request = require('request');
var express = require('express');
var router = express.Router();
/* GET data by sportId */
router.get('/:locale/:sportId/:federationId/:date', function(req, res) {
var date = req.params.date;
var locale = req.params.locale;
var sportId = req.params.sportId;
var federationId = req.params.federationId;
request(getEventsOptions(sportId, federationId, date, locale), function(error, response, body) {
res.send(body);
});
});
// get options for request
function getEventsOptions(sportId, federationId, date, locale)
{
return {
url: `http://myapi.com/sporting-event/sport/${sportId}/date-from/${date}`,
headers: {
'accept': 'application/json',
'dateTo': date,
'federationIds': federationId,
'X-Application-ID': 'sporter',
'Accept-Language': locale,
}
};
}
我收到一个对象数组(每个对象都是具有唯一eventId的体育游戏)。因此,每当我调用此路由时,我都会对api进行新的调用,我只想在事件的对象不同时(例如,如果游戏的分数已更改)询问api。您对如何做到这一点有想法吗?
答案 0 :(得分:0)
这是memoization服务的目的。由于getEventsOptions
接受标量参数,因此简化了应记住的方式;缓存键可以根据字符串化参数计算得出,例如Lodash memoize
或类似的实现方式:
function memoize(fn, getCacheKey = ([firstArg]) => firstArg) {
const cache = new Map();
return (...args) => {
const cacheKey = getCacheKey(args);
if (!cache.has(cacheKey))
cache.set(cacheKey, fn(...args));
return cache.get(cacheKey);
}
}
最好使用Promise,因为可以将Promise对象作为结果缓存,而使用基于回调的API则很难做到这一点。已通过官方request
软件包为request-promise
提供了承诺:
const request = require('request-promise');
function getEvents(sportId, federationId, date, locale)
{
const options = {
url: `http://myapi.com/sporting-event/sport/${sportId}/date-from/${date}`,
headers: {
'accept': 'application/json',
'dateTo': date,
'federationIds': federationId,
'X-Application-ID': 'sportytrader',
'Accept-Language': locale,
};
return request(options);
};
const getCachedEvents = memoize(
getEvents,
(...args) => JSON.stringify(args)
);
...
getCachedEvents(sportId, federationId, date, locale))
.then(body => res.send(body)
.catch(next);
请注意,由于JSON.stringify
的工作方式,这可能会影响请求的缓存方式,例如undefined
和null
参数没有区别。