Сделать искусственную задержку для fetch

Подскажите как сделать задержку для Fetch через setTimeout?

Есть такой вот метод:

const getSearchResult = search => {
    setLoading(true);
    fetch(`/api/search?query=${search}`)
      .then(response => {
        if (response.ok) {
          return response.json();
        } else if (response.status === 404) {
          history.push("/search");
        } else {
          throw response;
        }
      })
      .then(json => {
        setSearchResult(json);
        setLoading(false);
      });
  };

Нужно сделать так что бы данные отображались через минимум 1 секунду, но если данные не приходят дольше чем в 1 секунду loading должен продолжаться(Loader крутится), после получения данных убрать loader отобразить данные.

Вообщем так всё и работает. Но данные приходят слишком быстро и loader не успевает нормально отработать для этого и нужна задержка.

Спасибо )


Ответы (2 шт):

Автор решения: Сергей Петрашко

Можно попробовать добавить промис:

    const getSearchResult = (search) => {
    const start = Date.now();
    const getSearchResult = (search) => {
       fetch(`/api/search?query=${search}`).then(response => {
            return new Promise(resolve => {
                const diff  = Date.now() - start;
                if (diff < 1000) {
                    setTimeout(() => {
                        console.log('1000');
                        resolve(response);
                    }, 1000-diff);
                } else {
                    resolve(response);
                }
            });
        })
        .then(response => {
            if (response.ok) {
                return response.json();
            } else if (response.status === 404) {
                history.push('/search');
            } else {
                throw response;
            }
        })
        .then(json => {
            setSearchResult(json);
            setLoading(false);
        });
};

В коде замеряется время выполнения запроса.. и если он меньше 1000 мс то оставшееся время мы отображаем лодер иначе не отображаем его.

→ Ссылка
Автор решения: Grundy

Задержку можно вынести в Promise и затем дожидаться пока закончатся оба: и запрос и задержка, и только в этом случае убирать лоадер.

для создание Promise с явным временем разрешения можно использовать функцию delay

function delay(timeout){
    return new Promise(r=>setTimeout(r, timeout))
}

Для ожидания обоих Promise можно использовать Promise.all

function delay(timeout){
    return new Promise(r=>setTimeout(r, timeout))
}

const getSearchResult = search => {
    setLoading(true);
    Promise.all(delay(1000),
      fetch(`/api/search?query=${search}`)
        .then(response => {
          if (response.ok) {
            return response.json();
          } else if (response.status === 404) {
            history.push("/search");
          } else {
            throw response;
          }
        })
        .then(json => {
          setSearchResult(json);
        }))
      .then(()=>{
          setLoading(false);
      });
};    
→ Ссылка