Объединить несколько обещаний отмены в JS

#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);