Ссылка

я естьfetch-api POST запрос:

   fetch(url, {
      method: 'POST',
      body: formData,
      credentials: 'include'
    })

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

 Akshay Lokur26 окт. 2017 г., 07:43
@dandavis: хаха, спасибо тебе
 dandavis26 окт. 2017 г., 07:41
эти другие придурки бьют меня;) я думаю, что я печатаю слишком медленно ...
 dandavis26 окт. 2017 г., 07:36
afaik, тебе все равно придется обернуть его новым обещанием, которое ты можешь вручную отклонить. есть предложение ...
 Akshay Lokur26 окт. 2017 г., 07:37
@dandavis: Извините, не получил вас, пожалуйста, вы можете уточнить?

Ответы на вопрос(7)

Решение Вопроса

спецификация вообще не обсуждает таймауты

Вы можете реализовать свою собственную оболочку тайм-аута для обещаний в целом:

// Rough implementation. Untested.
function timeout(ms, promise) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      reject(new Error("timeout"))
    }, ms)
    promise.then(resolve, reject)
  })
}

timeout(1000, fetch('/hello')).then(function(response) {
  // process response
}).catch(function(error) {
  // might be a timeout error
})

Как описано вhttps://github.com/github/fetch/issues/175 Комментарий отhttps://github.com/mislav

суть с помощьюPromise.race

fetchWithTimeout.js

export default function (url, options, timeout = 7000) {
    return Promise.race([
        fetch(url, options),
        new Promise((_, reject) =>
            setTimeout(() => reject(new Error('timeout')), timeout)
        )
    ]);
}

main.js

import fetch from './fetchWithTimeout'

// call as usual or with timeout as 3rd argument

fetch('http://google.com', options, 5000) // throw after max 5 seconds timeout error
.then((result) => {
    // handle result
})
.catch((e) => {
    // handle errors and timeout error
})

завернув его в обещание.

например,

  function fetchWrapper(url, options, timeout) {
    return new Promise((resolve, reject) => {
      fetch(url, options).then(resolve).catch(reject);

      if (timeout) {
        const e = new Error("Connection timed out");
        setTimeout(reject, timeout, e);
      }
    });
  }
 dandavis26 окт. 2017 г., 07:48
мне больше нравится этот, менее повторяющийся, чтобы использовать более одного раза.
 Franklin Yu25 февр. 2018 г., 19:50
Firefox поддерживает его с 57 лет. :: смотрит на Chrome ::
 trysis03 февр. 2018 г., 07:32
Забавно, IE & Edge - единственные, кто поддерживает это! Если мобильный сайт Mozilla снова не работает ...
 trysis01 февр. 2018 г., 21:39
Запрос не отменяется после истечения времени ожидания здесь, правильно? Это может быть хорошо для OP, но иногда вы хотите отменить запрос на стороне клиента.
 code-jaff03 февр. 2018 г., 06:42
@trysis хорошо, да. Недавно реализовано решение для прерывания выборки сAbortController, но все еще экспериментальный с ограниченной поддержкой браузера.обсуждение

РЕДАКТИРОВАТЬ: Запрос на выборку будет по-прежнему выполняться в фоновом режиме и, скорее всего, зарегистрирует ошибку в вашей консоли.

Действительно, подход Promise.race лучше.

Смотрите эту ссылку для справкиPromise.race ()

Гонка означает, что все Обещания будут выполняться одновременно, и гонка остановится, как только одно из обещаний вернет значение. Следовательно,будет возвращено только одно значение, Вы также можете передать функцию для вызова, если время выборки истекло.

fetchWithTimeout(url, {
  method: 'POST',
  body: formData,
  credentials: 'include',
}, 5000, () => { /* do stuff here */ });

Если это вызывает у вас интерес, возможная реализация будет:

function fetchWithTimeout(url, options, delay, onTimeout) {
   const timer = new Promise((resolve) => {
      setTimeout(resolve, delay, {
      timeout: true,
     });
   });
   return Promise.race([
      fetch(path, request),
      timer
   ]).then(response) {
      if (response.timeout) { 
        onTimeout();
      }
      return response;
   }
}

const controller = new AbortController();
const signal = controller.signal;

const fetchPromise = fetch(url, {signal});

// 5 second timeout:
const timeoutId = setTimeout(() => controller.abort(), 5000);


fetchPromise.then(response => {
  // completed request before timeout fired

  // If you only wanted to timeout the request, not the response, add:
  // clearTimeout(timeoutId);
})

ВидетьAbortController страница на MDN.

 Michael Terry18 февр. 2019 г., 23:17
Лучше иметь этот ответ, чем нет ответа, потому что люди отталкивают придирками
 Karl Adler12 нояб. 2018 г., 16:16
Это выглядит даже лучше, чем решение обещания-гонки, потому что оно, вероятно, прерывает запрос, а не просто принимает более ранний ответ. Поправьте меня если я ошибаюсь.
 estus17 нояб. 2018 г., 12:05
Ответ не объясняет, что такое AbortController. Кроме того, он является экспериментальным и должен быть заполнен в неподдерживаемых движках, также это не синтаксис.
 Endless12 нояб. 2018 г., 21:22
Это верно. это прервет запрос
 Nobita05 дек. 2018 г., 10:44
Возможно, он не объясняет, что такое AbortController (я добавил ссылку на ответ, чтобы облегчить его для ленивых), но это лучший ответ на данный момент, поскольку он подчеркивает тот факт, что простое игнорирование запроса не означает, что он все еще не в ожидании Отличный ответ.
  fetchTimeout (url,options,timeout=3000) {
    return new Promise( (resolve, reject) => {
      fetch(url, options)
      .then(resolve,reject)
      setTimeout(reject,timeout);
    })
  }

Вы можете создать оболочку timeoutPromise

function timeoutPromise(timeout, err, promise) {
  return new Promise(function(resolve,reject) {
    promise.then(resolve,reject);
    setTimeout(reject.bind(null,err), timeout);
  });
}

Затем вы можете завернуть любое обещание

timeoutPromise(100, new Error('Timed Out!'), fetcn(...))
  .then(...)
  .catch(...)  

Это на самом деле не отменит базовое соединение, но позволит вам прервать обещание.
Ссылка

Ваш ответ на вопрос