Запуск функции в al oop одновременно - PullRequest
3 голосов
/ 25 апреля 2020

У меня есть javascript 1 oop, что довольно просто понять. По сути, он вызывает infoGetter() в al oop. Однако проблема в том, что он звонит infoGetter() 20 раз за раз. Я только хочу, чтобы всегда 3 infoGetters() работал в любой момент времени (если мы не достигли условия while l oop).

var min = 1;
var limit = 1000;
var myId = 12345;
while (min < limit) {
    var max = min + 50;
    infoGetter(myId, min, max);
    min = max;
}


function infoGetter(myId, min, max) {

    return $.ajax({
        type: "POST",
        url: "get-info.php",
        dataType: "json",
        data: {
            myId: myId,
            min: min,
            max: max
        },
        success: function(data) {
            /* to stuff here (not important to this question) */
        }
    });

}

Как мне нужен скрипт на работу:

  1. В l oop он вызывает infoGetter(myId, 1, 51); и ждет возврата значения в фоновом режиме
  2. Увеличивает min, вызывает infoGetter(myID, 51, 102); и ждет для возвращаемого значения в фоновом режиме
  3. Увеличивает min, он вызывает infoGetter(myID, 102, 153); и ждет возвращаемого значения в фоновом режиме

Теперь, как только один из infoGetter() получает возвращаемое значение он вызывает его снова с новыми параметрами (так как всегда необходимо, чтобы 3 infoGetter() работал одновременно, если только он не достигнет условия while l oop). Новые параметры, очевидно, будут новыми значениями myId, min, max, которые мы обновили, так как мы меняем min и max в l oop.

Где 3 может быть другим числом, например 5. Таким образом, мы можем запустить 5 infoGetter() одновременно.

1 Ответ

0 голосов
/ 25 апреля 2020

Вы можете создать функцию, которая вызывает infoGetter и рекурсивно вызывает себя, если есть дополнительные запросы, которые необходимо выполнить, приковав цепью к вызову ajax, возвращенному infoGetter. Затем вызовите эту функцию 3 раза, чтобы при каждом успешном выполнении запроса он снова вызывал makeRequest:

let min = 1;
const limit = 1000;
const myId = 12345;
const makeRequest = () => {
  const max = min + 50;
  infoGetter(myId, min, max)
    .then(() => {
      if (min < limit) {
        makeRequest();
      }
    });
  min = max;
};

makeRequest();
makeRequest();
makeRequest();

или

const maximumConcurrentRequests = 3;
for (let i = 0; i < maximumConcurrentRequests; i++) {
  makeRequest();
}

Если вы хотите, чтобы процесс продолжался, даже если запрос не выполняется, catch Обещание перед вызовом .then для него:

infoGetter(myId, min, max)
  .catch(() => void 0)
  .then(() => {

Или, в полном объеме:

let min = 1;
const limit = 1000;
const myId = 12345;
const makeRequest = () => {
  const max = min + 50;
  infoGetter(myId, min, max)
    .catch(() => void 0)
    .then(() => {
      if (min < limit) {
        makeRequest();
      }
    });
  min = max;
};

Демонстрация в реальном времени, где infoGetter моделируется с использованием Обещание, которое разрешается после случайного числа от 0 до 5 секунд:

const infoGetter = () => new Promise(res => setTimeout(res, Math.random() * 5000));

let min = 1;
const limit = 1000;
const myId = 12345;
const makeRequest = () => {
  console.log('making request for', min);
  const max = min + 50;
  infoGetter(myId, min, max)
    .catch(() => void 0)
    .then(() => {
      if (min < limit) {
        makeRequest();
      }
    });
  min = max;
};

const maximumConcurrentRequests = 3;
for (let i = 0; i < maximumConcurrentRequests; i++) {
  makeRequest();
}

Если вы также хотите определить, когда все запросы выполнены, поместите начальные обещания в массив, верните обещания из рекурсивных вызовов и вызовите Promise.all в массиве :

const infoGetter = () => new Promise(res => setTimeout(res, Math.random() * 5000));

let min = 1;
const limit = 500;
const myId = 12345;
const makeRequest = () => {
  console.log('making request for', min);
  const thisMin = min;
  const max = min + 50;
  min = max;
  return infoGetter(myId, thisMin, max)
    .catch(() => void 0)
    .then(() => {
      if (min < limit) {
        return makeRequest();
      }
    });
};

const maximumConcurrentRequests = 3;
Promise.all(
  Array.from(
    { length: maximumConcurrentRequests },
    makeRequest
  )
)
  .then(() => {
    console.log('All done');
  });
...