Показать сообщение отдельно
  #4 (permalink)  
Старый 06.12.2020, 02:57
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

такие штуковины надо делать в параметризуемом виде.
вот, с обработкой ошибок

// запускатель асинхронной функции для параметров
/*
args: {
  request: param => Promise
  getKey: param => value
  limit: number
  params: array
}
return [...]
*/
function runRequests(args) {
  if (!args.params) {
    return Promise.resolve([]);
  }
  return new Promise(res => {
    const results = new Array(args.params.length);
    const map = new Map();
    const req = []
    for (let i = 0; i < args.params.length; ++i) {
      const param = args.params[i];
      const key = args.getKey ? args.getKey(param) : param;
      let config = map.get(key);
      if (!config) {
        config = {
          param: param,
          indexes: [i]
        };
        map.set(key, config);
        req.push(config);
      } else {
        config.indexes.push(i);
      }
    }
    const limit = Math.min(args.limit || req.length, req.length);
    let pos = 0;
    let doneCount = 0;

    function run() {
      if (pos < req.length) {
        const config = req[pos++];
        args.request(config.param).then(
          data => done(false, data, config),
          error => done(true, error, config))
      }
    }

    function done(error, value, config) {
      // результат в комплексном виде, тут может быть как успешно, так и с ошибкой
      const item = {
        success: !error,
        data: error ? undefined : value,
        error: error ? value : undefined
      };
      for (let i = 0; i < config.indexes.length; ++i) {
        results[config.indexes[i]] = item
      }
      doneCount++;
      if (doneCount >= req.length) {
        res(results);
      } else {
        run();
      }
    }

    for (let i = 0; i < limit; ++i) {
      run();
    }
  });
}

// пример асинхронной функции, которая получает параметр и возвращает промис
function asyncReverse(value) {
  console.log('request ', value);
  return new Promise((res, rej) => {
    const r = Math.random();
    const delay = Math.floor(2000 + 3000 * Math.random());
    setTimeout(() => {
      if (r < 0.00002) {
        rej(r);
      } else {
        console.log('result for ', value);
        res(value.split('').reverse().join(''));
      }
    }, delay);
  });
}

// запуск для параметров
runRequests({
  request: asyncReverse, // асинхронная функция
  getKey: param => param, // ключ, по которому выявляем одинаковые параметры
  limit: 3,
  params: [
    '1234',
    'qazx',
    'rwsxc',
    'edcv',
    'rfvb',
    'edcv'
  ]
}).then(console.log)


смотреть в консоли результат можно

Последний раз редактировалось Alexandroppolus, 06.12.2020 в 02:59.
Ответить с цитированием