<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Fetch test with abort </h1>
<button id="btn">업데이트</button>
<main id="root"></main>
<script type="module">
const log = console.log;
const $ = (sel) => document.querySelector(sel);
const abortableFetch = (name, req, opts) => {
window.test = window.test || {};
if (window.test[name])
window.test[name]();
const controller = new AbortController();
const signal = controller.signal;
const abort = () => {
console.log('aborted!');
controller.abort();
};
window.test[name] = abort;
return request(req, { ...opts, signal });
}
const request = async (url, options) => {
try {
const res = await fetch(url, options);
if (res.ok)
return {
...(await res.json()),
error: 0
};
else
throw res;
} catch (res) {
const data = {};
if (res.name == 'AbortError') {
console.log(">>>>> ", res);
data = {
status: 500,
error: 2,
}
} else {
data = {
status: res.status,
error: 1,
};
console.log(res, data);
}
return data;
}
};
const API_ENDPOINT = 'https://oivhcpn8r9.execute-api.ap-northeast-2.amazonaws.com/dev';
const FATCH = 'FATCH';
const CAT = 'CAT';
const RANDOM = 'RANDOM';
const api = {
fetchCats: (keyword) =>
abortableFetch(FATCH, `${API_ENDPOINT}/api/cats/search?q=${keyword}`),
getCat: (id) => abortableFetch(CAT, `${API_ENDPOINT}/api/cats/${id}`),
getRandom: () => abortableFetch(RANDOM, `${API_ENDPOINT}/api/cats/random50`),
fetchGif: (keyword) => abortableFetch(`${API_ENDPOINT}/api/gif/search?q=${keyword}`),
fetchGifAll: () => abortableFetch(`${API_ENDPOINT}/api/gif/all`),
};
const root = $('#root');
const append = (child, parent) => parent.appendChild(child);
const templ = data => {
return data && data.map(({id, url, name}) => (
`
<div style="width: 200px; display: inline-block; flex: 2">
<p>${id}: ${name} </p>
<img src='${url}' style="width: 100px;">
</div>
`
)).join('')
};
let debounce = null;
$('#btn').addEventListener('click', (e) => {
if (debounce != null) {
clearTimeout(debounce);
log('hello');
}
debounce = setTimeout(async () => {
console.log('btn');
const datas = async () => await api.fetchCats('norway');
const d = await datas();
console.log('while', d);
const div = document.createElement('div');
div.style = "display: flex; flex-wrap: wrap; transform: translateY(100%); transition: none;"
div.innerHTML = templ(d.data);
root.innerHTML = '';
append(div, root);
setTimeout(() => {
div.style = "display: flex; flex-wrap: wrap; transform: translateY(0); transition: transform 2s;"
}, 1000);
}, 200);
});
</script>
</body>
</html>