Задача по мемоизации
Короче, застрял на задаче и никак не могу понять почему тренажёр не принимает решение, хотя у меня на компьютере всё работает. Вот условие: Функция getData ходит за данными и возвращает промис. Напишите кеширующую функцию memoize со следующим поведением:
Если getData ещё не была вызвана, вызывает её и кеширует результат;
Если вызывалась раньше заданного в функции времени — возвращает сохранённый результат;
Если вызывалась позже заданного в функции времени, нужно заново сходить за данными.
Она принимает функцию, сигнатура которой описана в getData, и время жизни кеша. Возвращает мемоизированную функцию. Используйте замыкание; Чтобы определить, была ли функция вызвана слишком рано или слишком поздно, просуммировать последнее время получения данных и время из аргумента, а потом сравните с текущим. Чтобы получить текущее время, вам поможет один из методов у Date.
А вот моё решение:
function memoize(data, delay){
let cache = {};
return async () => {
if(!("result" in cache) || await checkTime(cache.delay, cache.savedTime)){
cache.result = await data();
let date = await new Date();
cache.savedTime = await date.getTime();
cache.delay = delay;
}
return cache.result
}
}
async function checkTime(delay, savedTime){
let date = await new Date();
let currentTime = await date.getTime();
return savedTime + delay < currentTime;
}
function getData() {
return new Promise(resolve => {
setTimeout(() => resolve(42), 1000)
})
}
const memoized = memoize(getData, 1000);
memoized()
.then(data1 => console.log(data1)) // получаем долго
.then(memoized)
.then(data2 => console.log(data2)) // получаем быстро, из кеша
.then(memoized)
.then(data3 => console.log(data3)) // получаем быстро, из кеша
.then(() => {
setTimeout(() => {
return memoized().then(data4 => console.log(data4)); // получаем долго, считается заново
}, 5000);
});
Ответы (1 шт):
Мемоизация предполагает работу на все приложение. Ниже реализация.
Основное из того, что было изменено. Данные были вынесены из функции, иначе при повторном вызове, это были бы другие данные. Реализована передача ожидающего промиса.
Функция sleepRnd написана для тестирования
const cache = {
result: null,
timeUpd: 0,
wait: null,
sleepeng: true
};
function memoize(data, delay){
return async () => {
if (cache.sleepeng && (new Date().getTime() - cache.timeUpd > delay || !cache.result)) {
cache.sleepeng = false;
cache.wait = data();
cache.result = await cache.wait;
cache.wait = null;
cache.sleepeng = true;
cache.timeUpd = new Date().getTime();
} else {
if (!cache.sleepeng) {
return await cache.wait;
}
}
return cache.result;
}
}
function getData() {
return new Promise(resolve => {
setTimeout(() => resolve(Math.round(Math.random() * 5000)), 1000)
})
}
const memoized = memoize(getData, 1000);
const sleepRnd = () => {
return new Promise(resolve => {
const delay = Math.round(Math.random() * 400);
setTimeout(() => resolve(), delay)
})
}
memoized()
.then(async data1 => {
console.log('F01', data1)
await sleepRnd();
}) // получаем долго
.then(memoized)
.then(async data2 => {
console.log('F02',data2)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F03',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(() => {
setTimeout(() => {
memoized().then(data4 => console.log('T', data4)).catch(e => console.log('Error1', e)); // получаем долго, считается заново
}, 5000);
});
memoized()
.then(async data1 => {
console.log('F11', data1)
await sleepRnd();
}) // получаем долго
.then(memoized)
.then(async data2 => {
console.log('F12',data2)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F13',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F13',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F13',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F13',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F13',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F13',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(memoized)
.then(async data3 => {
console.log('F13',data3)
await sleepRnd();
}) // получаем быстро, из кеша
.then(() => {
setTimeout(() => {
memoized().then(data4 => console.log('F14', data4)).catch(e => console.log('Error1', e)); // получаем долго, считается заново
}, 5000);
});