js fetch 요청 취소, 중단하기

example.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let controller;

const fetchData = async (pram) => {
try {
console.log(`fetchData`);
if (controller) controller.abort();
controller = new AbortController();
const { signal } = controller;

const res = await fetch(`${API_END_POINT}/${pram}`, { signal });

if (!res.ok) {
throw new Error('no ok error');
}

return await res.json();
} catch (error) {
throw new Error('server error');
}
};
  • AbortController를 사용해서 기존에 요청이 있으면
  • 취소하고 새로운 요청을 보내는 예제이다
  • 버튼을 눌러서 fetchData를 실행시킨다고 하자
  • 유저가 빠르게 버튼 10번을 눌러서 fetchData가 10번 실행되었다
  • 이런 입력에 대한 아무런 방지를 않았으면, fetch 결과에 대한 콜백이 10번 실행될 것이다
  • AbortController을 사용하면 버튼을 연속적으로 누르더라도 콜백이 마지막 결과에 대해서만 한번 동작할 것이다
  • 하지만 AbortController를 사용한다고 해서 API를 콜하는 비용이 덜 드는 것은 아니다
  • 단순히 해당 fetch에 대한 결과를 핸들하지 않겠다는 것이기 때문에,
  • 지금의 예처럼 동일한 API를 중복해서 호출하는 것을 막기 위해서는
  • 최초에 버튼을 누르면 버튼을 비활성화하는 것이 좋다

참고

reqres.in으로 ajax 연습하기

  • Reqres 에서 다양한 api를 제공하고있다
  • cors를 허용하기 때문에 localhost에서도 요청을보내고 응답을 받을 수 있다
  • ajax 연습이나, 간단한 앱을 만들 때, 서버를 만들지 않고,
  • reqres에서 제공하는 api를 사용할 수 있겠다

get api

https://reqres.in/api/users?page=2 // 유저 목록 2페이지 보기
https://reqres.in/api/users/2 // 2번 유저 보기
https://reqres.in/api/users/23 // 23번 유저 보기(없는 유저)

// products보기, products 부분은 어떤 문자열로든 치환이 가능해서 원하는 느낌의 문자열을 적어주면된다
https://reqres.in/api/products
https://reqres.in/api/products/1

fetch api 연습

1
2
3
4
5
6
7
8
9
10
fetch('http://localhost:3000/users')
.then(function (response) {
return response.json();
})
.then(function (myJson) {
console.log(JSON.stringify(myJson));
})
.catch(function (error) {
console.log(error);
});

fetch api 써먹기

users router
1
2
3
4
5
let users = [];

app.get('/users', (req, res) => {
return res.json(users);
});
fetch api
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function getUserList() {
// listbox 초기화
let newListbox = document.createElement('li');
newListbox.innerHTML = `<li class="list-group-item head">User List</li>`;

const url = '/users';
const fetchResponsePromise = fetch(url);
fetchResponsePromise
.then((response) => {
if (response.status === 200) {
return response.json();
} else {
throw new Error('Something went wrong on api server!');
}
})
.then((response) => {
console.log(`fetch`, response);
let i = 0;
for (const key in response) {
i++;
if (response.hasOwnProperty(key)) {
const element = response[key];

const new_li_element = document.createElement('li');
new_li_element.className = 'list-group-item';
new_li_element.appendChild(document.createTextNode(element));
newListbox.appendChild(new_li_element);
}
}
listbox.innerHTML = newListbox.innerHTML;
})
.catch((error) => {
console.error(error);
});
}
  • users라는 라우터에서는 유저배열을 반환한다
  • 유저배열을 json으로 받는데, 그걸 받아서 화면에서 유저목록을 갱신한다
  • 나는 ajax하면 xhr객체를 만들어서 가져오곤 했는데 이번에는 fetch를 사용해 보았다
  • fetch가 간단하고 간결한 것 같다