Избыточная задержка с жестко заданным временем разрешения - PullRequest
0 голосов
/ 17 декабря 2018

Я попытался посчитать запрос - время ответа программно, и в итоге получил следующий код:

function fakeRequest(wait) {
  return new Promise(resolve => {
    setTimeout(() => resolve(wait), wait);
  });
}

function calculateTime(fn, params) {
  const startTime = new Date().getTime();
  fn(...params)
    .then(response => {
      const endTime = new Date().getTime();
      const requestTime = endTime - startTime;
      console.log(`
        Request should take ${response} ms
        Request took ${requestTime} ms
      `);
    });
}

calculateTime(fakeRequest, [2000]);

В этом примере у нас есть жестко закодированное время разрешения (2000 миллисекунд), и, как я понимаю, конечный результат должен быть таким же - 2 секунды.Но когда я запускаю этот код на своей машине, он дает мне разные результаты между 2000 мс и 2003 мс .

Я пытаюсь выяснить, где эти 3 миллисекундыприходят от:

  1. Причина - время выполнения new Date().getTime().(но если да, то почему мы получаем разные результаты в период между 2000 и 2003 годами, почему они не одинаковы при каждом выполнении?).

  2. Причина - асинхронный характер запроса, дажехотя оно имеет жестко закодированное время разрешения.

  3. Что-то еще.

Я хотел бы услышать ваши мысли и найтиспособ получить реальное время ответа (в данном случае 2 секунды).

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Если вы замените setTimeout(resolve, wait, wait) на resolve(wait), вы получите ~ 5 мс.Вероятно, это связано с двумя причинами:

1) Date.now() возвращает не точное время.

2) Обещания всегда разрешаются асинхронно, поэтому существует небольшая задержка до следующего такта двигателя.

Таким образом, даже если setTimeout будет точным (или если вы не дразните запрос), вы все равно не получите точного результата.И нет возможности.И на самом деле я не вижу причин, по которым эта миллисекунда имела бы значение.

0 голосов
/ 18 декабря 2018

Несмотря на то, что Феликс прав в этом setTimeout не может гарантировать точное время обратного вызова, есть некоторые вещи, которые следует отметить с вашим кодом.Вы не рассчитываете время окончания как можно раньше (после разрешения).Мой тест получился чуть ближе к нужному времени ниже.Я хочу сказать, что даже если ваш setTimeout был точным, я не думаю, что ваш журнал все равно будет правильным.

var closeEnd

function fakeRequest(wait) {
  return new Promise(resolve => {
    setTimeout(() => {
      closeEnd = performance.now()
      resolve(wait)
    }, wait);
  })  
}

function calculateTime(fn, params) {
  const startTime = performance.now()
  console.log(startTime)
  fn(...params)
    .then(response => {      
      const requestTime = closeEnd - startTime;      
      console.log(`
        Request should take ${response} ms
        Request took ${requestTime} ms
      `);
    });
}

calculateTime(fakeRequest, [2000]);
...