#javascript #npm #es6-promise
#javascript #npm #es6-обещание
Вопрос:
Я хотел бы оптимизировать несколько дорогостоящих вызовов сервера, многократно вызывая функцию, которая принимает ключ и возвращает обещание объекта. При разрешении объект гарантированно будет содержать необходимый ключ некоторое значение, и он может содержать другие несвязанные ключи. Функция будет:
- при первом вызове создайте обещание
- при каждом вызове накапливаются ключи для отправки на сервер
- все вызовы возвращают одно и то же обещание до 100 мс времени ожидания
- если в течение 100 мс не выполняется никаких вызовов, вызовите сервер для обработки всех ключей, накопленных до сих пор
- если выполняется новый вызов, даже если сервер еще не ответил, обработайте его как «первый вызов», запустив новое обещание с его собственным набором ожидающих ключей
- когда вызов сервера вернется, разрешите ожидающее обещание
Существуют ли какие-либо библиотеки NPM, которые могли бы помочь в этом, или я должен написать это с нуля?
Комментарии:
1. Что касается части «гарантии» — если консолидированное обещание отклоняется из-за сбоя связи, все получатели обещания могут перехватить отклонение. Но если конкретный ключ неизвестен, получатели действительных ключей должны продолжить. Итак, мое предложение состояло бы в том, чтобы вернуть недопустимое значение с сервера для отдельных недопустимых ключей. В остальном алгоритм выглядит нормально (28 строк кода для макета;-))
Ответ №1:
Поиск «NPM консолидирует запросы сервера с использованием одного обещания» или «… накапливайте запросы сервера… » не обнаружил ничего очевидного. Я поделюсь кодом макета, используя обещания ES6, упомянутые в комментарии, чтобы, возможно, составить основу решения в отсутствие других предложений. Как есть, не гарантируется и т.д…
/******* application code ********/
function requestKeys( keyArray) {
// promise an oject for values of keys in keyArray:
// use asynchronous code to get values for keys in keyArray,
// return a promise for the parsed result object.
// ...
}
const latency = 100; // maximum latency between getting a key and making a request
/******** generic code *********/
var getKey = (( requestKeys, latency) => {
// return a function to return a promise of a key value object
var promise = null;
var resolve = null;
var reject = null;
var pendingKeys = null;
var defer = () => {
promise = new Promise( (r,j) => {resolve = r; reject = j});
pendingKeys = [];
};
var running = false;
var timesUp = () => {
resolve( requestKeys( pendingKeys));
running = false;
}
var addKey = ( key) => {
if(! running) {
defer();
setTimeout( timesUp, latency);
running = true;
}
pendingKeys.push( key);
return promise;
}
return addKey;
})( requestKeys, latency);
/******* test code *******/
// redefine requestKeys to promise an object with key strings as key values,
// resolve the return promise synchronously for testing:
function requestKeys( keyArray) {
var keyObj = keyArray.reduce( ((obj, v) => ((obj[v] = v), obj) ), {} );
return new Promise( (resolve, reject) => resolve(keyObj) );
}
var log = obj => console.log( JSON.stringify(obj));
// get two keys quickly
getKey("holas").then( log);
getKey("buono").then( log);
// wait and get another
setTimeout( function(){getKey('later').then( log)}, 500);