初めに
非同期処理は慣れるまで時間がかかるものです。
私が後輩に非同期処理について説明するときに、スムーズに伝えることができなかったのでメモすることにしました。
非同期処理のコード例
const executeApi = async (
currentPath = null,
method = "GET",
body = null,
tokenKey = cookieIdTokenKey
) => {
const options = {
method,
headers: getAuthHeaders(tokenKey),
};
if (body) {
options.body = JSON.stringify(body);
}
return new Promise((resolve, reject) => {
fetch("hoge", options)
.then((response) => {
if (!response.ok) {
if (response.status === 401) {
deleteAuthToken();
return response.json().then((error) => {
reject(error.message);
router.push({
path: "/login",
query: currentPath ? { redirect: currentPath } : {},
});
});
}
return response.json().then((error) => reject(error.message));
}
response.json().then((responseJson) => resolve(responseJson));
})
.catch((error) => {
reject(errorMessages.networkError);
});
});
};
・async
は、async前の関数はpromiseを返すことを宣言している
・fetch
自体がpromise
を返すので、fetch
のprimise
がresolve
を返せば.then
の処理が走り、reject
を返せば.catch
が走る。
・fetchの.thenか.catchの中で、resolveやrejectは、return new Promise((resolve, reject)
で受け取る
promiseがどこで返されるのか理解できれば追うのは容易です。
使用例
同ファイル内で昨日ごとに引数を設定してexecuteApiをインスタンス化し、別ファイルで使えるようにexportしておく
const login = (body) => executeApi("login", null, "POST", body);
export default {login}
別ファイルで使いたい時は以下のようにする
const login = async () => {
const data = {
email: email.value,
password: password.value,
};
loading.value = true;
api
.login(data)
.then((response) => {
if (response === "Aborted") {
return;
}
const redirectPath = route.query.redirect;
router.push(redirectPath || "/");
})
.catch((errorMessage) => alert(errorMessage))
.finally(() => (loading.value = false));
};
api.login(data)はpromiseを返すので、resolveなら.thenでrejectなら.catchが走る