[JS]非同期-Promiseとfetch API,Event Loop
14896 ワード
コースソース:完全JavaScript Course 2022 Jonas(Udemy)
PromisesとFetch API XMLHttpRequest로 사이트 받는 형태
const request = new XMLHttpRequest();
request.open('GET', `https://restcountries.com/v2/name/${country}`);
request.send();
Fetch API
const request = fetch('https://restcountries.com/v2/name/portugal');
console.log(request); // return promise
fetch関数は、すぐに承諾を返す特徴があります.
Promise
Promise:Promiseオブジェクトは、同期操作による将来の成功または失敗とその結果の値を表します.プロセスを作成するときに、不明な値の可能性のあるエージェントを指定し、非同期操作が終了した後に結果値と処理に失敗した理由にプロセッサを接続できます.「≪基本情報|Basic Information|emdw≫」を使用すると、非同期メソッドは同期メソッドのように値を返すことができます.ただし、最終結果ではなく、将来のある時点で結果を提供する「承諾」(Promis)を返します.
簡単に言えば、非同期伝達値を持つコンテナです.あるいは、未来値の容器ともいえる.
将来の値の例:AJAXからの応答
初めて応答を聞いたときは価値がありませんが、これから何が起こるか知ることができます.
Promiseのメリット
XMLHttpRequest로 사이트 받는 형태
const request = new XMLHttpRequest();
request.open('GET', `https://restcountries.com/v2/name/${country}`);
request.send();
const request = fetch('https://restcountries.com/v2/name/portugal');
console.log(request); // return promise
We no longer need to rely on events and callbacks passed into asynchronous functions to handle asynchronous results
Promiseは宝くじのようです.もし私が正しい結果値を予想したら、私はお金を手に入れます.そうしないと、私は手に入れられません.宝くじの抽選は非同期です.
lottery ticket that I will receive money if I guess correnct outcome
The Promise lifecycle
--Async Task-->
2つの異なる状況における承諾状態を処理しなければならない.
Consuming Promises
次のコードから応答のbodyにアクセスするには、jsonを使用する必要があります.jsonはもう一つの承諾が返される特徴を持っている.const renderCountry = function (data, className = '') {
const html = ` <article class="country ${className}">
<img class="country__img" src="${data.flag}" />
<div class="country__data">
<h3 class="country__name">${data.name}</h3>
<h4 class="country__region">${data.region}</h4>
<p class="country__row"><span>👫</span>${(
+data.population / 10000000
).toFixed(1)} people</p>
<p class="country__row"><span>🗣️</span>${data.languages[0].name}</p>
<p class="country__row"><span>💰</span>${data.currencies[0].name}</p>
</div>
</article>`;
countriesContainer.insertAdjacentHTML('beforeend', html);
countriesContainer.style.opacity = 1;
};
const renderError = function (msg) {
countriesContainer.insertAdjacentText('beforeend', msg);
countriesContainer.style.opacity = 1;
};
const getCountryData = function (country) {
fetch(`https://restcountries.com/v2/name/${country}`)
.then(response => response.json())
.then(data => renderCountry(data[0]));
};
getCountryData('portugal');
Chaining Promises
& Handling Rejected Promise const getCountryData = function (country) {
//country 1
fetch(`https://restcountries.com/v2/name/${country}`)
.then(response => {
//Throwing errors manually
if (!response.ok) throw new Error(`Country not found ${response.status}`);
return response.json();
})
.then(data => {
renderCountry(data[0]);
const neighbor = data[0].borders[0];
if (!neighbor) return;
//country 2
return fetch(`https://restcountries.com/v2/alpha/${neighbor}`);
})
.then(response => {
if (!response.ok) throw new Error(`Country not found ${response.status}`);
return response.json();
})
.then(data => renderCountry(data, 'neighbour'))
.catch(err => {
console.error(`${err}💥💥💥`); //Failed to fetch💥💥💥
renderError(`Something went wrong 💥💥 ${err.message}. Try again!`); //user들도 화면에서 볼 수 있도록
})
.finally(() => {
countriesContainer.style.opacity = 1;
});
};
getJSONという名前の関数簡略化コードを作成するconst getJSON = function (url, errorMsg = 'Something went wrong') {
return fetch(url).then(response => {
if (!response.ok) throw new Error(`${errorMsg} (${response.status})`);
return response.json();
});
};
const getCountryData = function (country) {
//country 1
getJSON(`https://restcountries.com/v2/name/${country}`, 'Country not found')
.then(data => {
renderCountry(data[0]);
const neighbor = data[0].borders[0];
if (!neighbor) throw new Error('No neighbor found!');
//country 2
return getJSON(
`https://restcountries.com/v2/alpha/${neighbor}`,
'Country not found'
);
})
.then(data => renderCountry(data, 'neighbour'))
.catch(err => {
console.error(`${err}💥💥💥`); //Failed to fetch💥💥💥
renderError(`Something went wrong 💥💥 ${err.message}. Try again!`); //user들도 화면에서 볼 수 있도록
})
.finally(() => {
countriesContainer.style.opacity = 1;
});
};
btn.addEventListener('click', function () {
getCountryData('portugal');
});
getCountryData('dfasdfadsf');
// 찾을 수 없는 값을 넣을 경우 promise는 reject로 인식하지 않는다. promise는 오직 internet connection이 되지 않았을 때만 reject로 인식! error를 undefined (reading 'flag')라고 표현. That's not what we want.
手動でerror処理を行うと、throw new error("")!
Asynchronous Behind the Scenes : The Event Loop
Runtime in the Browser : 'Container' which includes all the pieces necessary to execute JavaScript code
JS engine : "Heart of the runtime"
Heap : Where object are stored in memory
Call stack : Where code is actually executed -> only ONE thread of execution. No multitasking!
WEB API:API privided to the engine(JS内ではありません!)
Callback Queue : Ready to be executed callback functions(coming from events)
Concurrency model : How JavaScript handles multiple tasks happening at the same time
How Asynchronous JavaScript Works Behind the scenes
el = documemt.querySelector('img');
el.src = 'dog.jpg';
el.addEventListner('load',()=> {
el.classList.add('fadeIn');
});
fetch('http://someurl.com/api')
.then(res => console.log(res))
'dog.jpg'は呼び出しスタック(main thread of execution)内で完了するのではなく、Web API環境自体で完了する.=>ひどうきコード
WEB API:非同期トランザクションを扱う場所
画像ロード中、load event内でコールバック関数が待機します.loadが終了すると、コールバックキューにコールバック関数が追加されます.
データ取得中は、次のコールバック関数webappisで待機します.
fetchが完了すると、マイクロタスクキューに移動されます.(callback queueより優先されます.イベントループはcallback queueのコールバック関数より先になります.)
コールバックキューのコールバック関数は、イベントループがcallstackに移動するのを待つ.callスタックの関数が空の場合、すぐに発生します.
要旨:WEB APIとイベントループがブロックされない非同期コードを実行できるようにする.
Building a Simple Promise
new Promise(executer function)const lotteryPromise = new Promise(function (resolve, reject) {
console.log('Lottery draw is happening 💎');
setTimeout(function () {
if (Math.random() >= 0.5) {
resolve('You WIN 💰');
} else {
reject(new Error('You lost your money 💩'));
}
}, 2000);
});
lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
別の例-settimeout premizationconst wait = function (seconds) {
return new Promise(function (resolve) {
setTimeout(resolve, seconds * 1000);
});
};
wait(2)
.then(() => {
console.log('1 second passed');
return wait(1);
})
.then(() => {
console.log('2 second passed');
return wait(1);
})
.then(() => {
console.log('3 second passed');
return wait(1);
})
.then(() => {
console.log('4 second passed');
return wait(1);
});
콜백지옥과 비교
setTimeout(() => {
console.log('1 second passed');
setTimeout(() => {
console.log('2 seconds passed');
setTimeout(() => {
console.log('3 seconds passed');
}, 1000);
setTimeout(() => {
console.log('4 seconds passed');
}, 1000);
}, 1000);
}, 1000);
Promise resolveと拒否関数の作成と実行Promise.resolve('abc').then(x => console.log(x));
Promise.reject(new Error('Problem!')).catch(x => console.error(x));
Promisifying the Geolocation API const getPosition = function () {
return new Promise(function (resolve, reject) {
// navigator.geolocation.getCurrentPosition(
// position => resolve(position),
// err => reject(err)
// );
navigator.geolocation.getCurrentPosition(resolve, reject);
});
};
getPosition()
.then(pos => console.log(pos))
.catch(err => console.error(err));
const whereAmI = function () {
getPosition()
.then(pos => {
const { latitude: lat, longitude: lng } = pos.coords;
return fetch(`https://geocode.xyz/${lat},${lng}?geoit=json`);
})
.then(response => {
if (!response.ok)
throw new Error(`Problem with geocoding ${response.status}`);
return response.json();
})
.then(data => {
//console.log(data);
const { region, country } = data;
console.log(`You are in ${region}`);
return fetch(`https://restcountries.com/v2/name/${country}`);
})
.then(response => {
if (!response.ok)
throw new Error(`Country not found (${response.status})`);
return response.json();
})
.then(data => renderCountry(data[0]))
.catch(err => console.error(`${err.message} 💥`));
};
Reference
この問題について([JS]非同期-Promiseとfetch API,Event Loop), 我々は、より多くの情報をここで見つけました
https://velog.io/@hoje15v/비동기-Promise-Event-Loop
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
const renderCountry = function (data, className = '') {
const html = ` <article class="country ${className}">
<img class="country__img" src="${data.flag}" />
<div class="country__data">
<h3 class="country__name">${data.name}</h3>
<h4 class="country__region">${data.region}</h4>
<p class="country__row"><span>👫</span>${(
+data.population / 10000000
).toFixed(1)} people</p>
<p class="country__row"><span>🗣️</span>${data.languages[0].name}</p>
<p class="country__row"><span>💰</span>${data.currencies[0].name}</p>
</div>
</article>`;
countriesContainer.insertAdjacentHTML('beforeend', html);
countriesContainer.style.opacity = 1;
};
const renderError = function (msg) {
countriesContainer.insertAdjacentText('beforeend', msg);
countriesContainer.style.opacity = 1;
};
const getCountryData = function (country) {
fetch(`https://restcountries.com/v2/name/${country}`)
.then(response => response.json())
.then(data => renderCountry(data[0]));
};
getCountryData('portugal');
& Handling Rejected Promise const getCountryData = function (country) {
//country 1
fetch(`https://restcountries.com/v2/name/${country}`)
.then(response => {
//Throwing errors manually
if (!response.ok) throw new Error(`Country not found ${response.status}`);
return response.json();
})
.then(data => {
renderCountry(data[0]);
const neighbor = data[0].borders[0];
if (!neighbor) return;
//country 2
return fetch(`https://restcountries.com/v2/alpha/${neighbor}`);
})
.then(response => {
if (!response.ok) throw new Error(`Country not found ${response.status}`);
return response.json();
})
.then(data => renderCountry(data, 'neighbour'))
.catch(err => {
console.error(`${err}💥💥💥`); //Failed to fetch💥💥💥
renderError(`Something went wrong 💥💥 ${err.message}. Try again!`); //user들도 화면에서 볼 수 있도록
})
.finally(() => {
countriesContainer.style.opacity = 1;
});
};
getJSONという名前の関数簡略化コードを作成するconst getJSON = function (url, errorMsg = 'Something went wrong') {
return fetch(url).then(response => {
if (!response.ok) throw new Error(`${errorMsg} (${response.status})`);
return response.json();
});
};
const getCountryData = function (country) {
//country 1
getJSON(`https://restcountries.com/v2/name/${country}`, 'Country not found')
.then(data => {
renderCountry(data[0]);
const neighbor = data[0].borders[0];
if (!neighbor) throw new Error('No neighbor found!');
//country 2
return getJSON(
`https://restcountries.com/v2/alpha/${neighbor}`,
'Country not found'
);
})
.then(data => renderCountry(data, 'neighbour'))
.catch(err => {
console.error(`${err}💥💥💥`); //Failed to fetch💥💥💥
renderError(`Something went wrong 💥💥 ${err.message}. Try again!`); //user들도 화면에서 볼 수 있도록
})
.finally(() => {
countriesContainer.style.opacity = 1;
});
};
btn.addEventListener('click', function () {
getCountryData('portugal');
});
getCountryData('dfasdfadsf');
// 찾을 수 없는 값을 넣을 경우 promise는 reject로 인식하지 않는다. promise는 오직 internet connection이 되지 않았을 때만 reject로 인식! error를 undefined (reading 'flag')라고 표현. That's not what we want.
手動でerror処理を行うと、throw new error("")!
Asynchronous Behind the Scenes : The Event Loop
Runtime in the Browser : 'Container' which includes all the pieces necessary to execute JavaScript code
JS engine : "Heart of the runtime"
Heap : Where object are stored in memory
Call stack : Where code is actually executed -> only ONE thread of execution. No multitasking!
WEB API:API privided to the engine(JS内ではありません!)
Callback Queue : Ready to be executed callback functions(coming from events)
Concurrency model : How JavaScript handles multiple tasks happening at the same time
How Asynchronous JavaScript Works Behind the scenes
el = documemt.querySelector('img');
el.src = 'dog.jpg';
el.addEventListner('load',()=> {
el.classList.add('fadeIn');
});
fetch('http://someurl.com/api')
.then(res => console.log(res))
'dog.jpg'は呼び出しスタック(main thread of execution)内で完了するのではなく、Web API環境自体で完了する.=>ひどうきコード
WEB API:非同期トランザクションを扱う場所
画像ロード中、load event内でコールバック関数が待機します.loadが終了すると、コールバックキューにコールバック関数が追加されます.
データ取得中は、次のコールバック関数webappisで待機します.
fetchが完了すると、マイクロタスクキューに移動されます.(callback queueより優先されます.イベントループはcallback queueのコールバック関数より先になります.)
コールバックキューのコールバック関数は、イベントループがcallstackに移動するのを待つ.callスタックの関数が空の場合、すぐに発生します.
要旨:WEB APIとイベントループがブロックされない非同期コードを実行できるようにする.
Building a Simple Promise
new Promise(executer function)const lotteryPromise = new Promise(function (resolve, reject) {
console.log('Lottery draw is happening 💎');
setTimeout(function () {
if (Math.random() >= 0.5) {
resolve('You WIN 💰');
} else {
reject(new Error('You lost your money 💩'));
}
}, 2000);
});
lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
別の例-settimeout premizationconst wait = function (seconds) {
return new Promise(function (resolve) {
setTimeout(resolve, seconds * 1000);
});
};
wait(2)
.then(() => {
console.log('1 second passed');
return wait(1);
})
.then(() => {
console.log('2 second passed');
return wait(1);
})
.then(() => {
console.log('3 second passed');
return wait(1);
})
.then(() => {
console.log('4 second passed');
return wait(1);
});
콜백지옥과 비교
setTimeout(() => {
console.log('1 second passed');
setTimeout(() => {
console.log('2 seconds passed');
setTimeout(() => {
console.log('3 seconds passed');
}, 1000);
setTimeout(() => {
console.log('4 seconds passed');
}, 1000);
}, 1000);
}, 1000);
Promise resolveと拒否関数の作成と実行Promise.resolve('abc').then(x => console.log(x));
Promise.reject(new Error('Problem!')).catch(x => console.error(x));
Promisifying the Geolocation API const getPosition = function () {
return new Promise(function (resolve, reject) {
// navigator.geolocation.getCurrentPosition(
// position => resolve(position),
// err => reject(err)
// );
navigator.geolocation.getCurrentPosition(resolve, reject);
});
};
getPosition()
.then(pos => console.log(pos))
.catch(err => console.error(err));
const whereAmI = function () {
getPosition()
.then(pos => {
const { latitude: lat, longitude: lng } = pos.coords;
return fetch(`https://geocode.xyz/${lat},${lng}?geoit=json`);
})
.then(response => {
if (!response.ok)
throw new Error(`Problem with geocoding ${response.status}`);
return response.json();
})
.then(data => {
//console.log(data);
const { region, country } = data;
console.log(`You are in ${region}`);
return fetch(`https://restcountries.com/v2/name/${country}`);
})
.then(response => {
if (!response.ok)
throw new Error(`Country not found (${response.status})`);
return response.json();
})
.then(data => renderCountry(data[0]))
.catch(err => console.error(`${err.message} 💥`));
};
Reference
この問題について([JS]非同期-Promiseとfetch API,Event Loop), 我々は、より多くの情報をここで見つけました
https://velog.io/@hoje15v/비동기-Promise-Event-Loop
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
const getCountryData = function (country) {
//country 1
fetch(`https://restcountries.com/v2/name/${country}`)
.then(response => {
//Throwing errors manually
if (!response.ok) throw new Error(`Country not found ${response.status}`);
return response.json();
})
.then(data => {
renderCountry(data[0]);
const neighbor = data[0].borders[0];
if (!neighbor) return;
//country 2
return fetch(`https://restcountries.com/v2/alpha/${neighbor}`);
})
.then(response => {
if (!response.ok) throw new Error(`Country not found ${response.status}`);
return response.json();
})
.then(data => renderCountry(data, 'neighbour'))
.catch(err => {
console.error(`${err}💥💥💥`); //Failed to fetch💥💥💥
renderError(`Something went wrong 💥💥 ${err.message}. Try again!`); //user들도 화면에서 볼 수 있도록
})
.finally(() => {
countriesContainer.style.opacity = 1;
});
};
const getJSON = function (url, errorMsg = 'Something went wrong') {
return fetch(url).then(response => {
if (!response.ok) throw new Error(`${errorMsg} (${response.status})`);
return response.json();
});
};
const getCountryData = function (country) {
//country 1
getJSON(`https://restcountries.com/v2/name/${country}`, 'Country not found')
.then(data => {
renderCountry(data[0]);
const neighbor = data[0].borders[0];
if (!neighbor) throw new Error('No neighbor found!');
//country 2
return getJSON(
`https://restcountries.com/v2/alpha/${neighbor}`,
'Country not found'
);
})
.then(data => renderCountry(data, 'neighbour'))
.catch(err => {
console.error(`${err}💥💥💥`); //Failed to fetch💥💥💥
renderError(`Something went wrong 💥💥 ${err.message}. Try again!`); //user들도 화면에서 볼 수 있도록
})
.finally(() => {
countriesContainer.style.opacity = 1;
});
};
btn.addEventListener('click', function () {
getCountryData('portugal');
});
getCountryData('dfasdfadsf');
// 찾을 수 없는 값을 넣을 경우 promise는 reject로 인식하지 않는다. promise는 오직 internet connection이 되지 않았을 때만 reject로 인식! error를 undefined (reading 'flag')라고 표현. That's not what we want.
Runtime in the Browser : 'Container' which includes all the pieces necessary to execute JavaScript code
JS engine : "Heart of the runtime"
Heap : Where object are stored in memory
Call stack : Where code is actually executed -> only ONE thread of execution. No multitasking!
WEB API:API privided to the engine(JS内ではありません!)
Callback Queue : Ready to be executed callback functions(coming from events)
Concurrency model : How JavaScript handles multiple tasks happening at the same time
How Asynchronous JavaScript Works Behind the scenes
el = documemt.querySelector('img');
el.src = 'dog.jpg';
el.addEventListner('load',()=> {
el.classList.add('fadeIn');
});
fetch('http://someurl.com/api')
.then(res => console.log(res))
'dog.jpg'は呼び出しスタック(main thread of execution)内で完了するのではなく、Web API環境自体で完了する.=>ひどうきコードWEB API:非同期トランザクションを扱う場所
画像ロード中、load event内でコールバック関数が待機します.loadが終了すると、コールバックキューにコールバック関数が追加されます.
データ取得中は、次のコールバック関数webappisで待機します.
fetchが完了すると、マイクロタスクキューに移動されます.(callback queueより優先されます.イベントループはcallback queueのコールバック関数より先になります.)
コールバックキューのコールバック関数は、イベントループがcallstackに移動するのを待つ.callスタックの関数が空の場合、すぐに発生します.
要旨:WEB APIとイベントループがブロックされない非同期コードを実行できるようにする.
Building a Simple Promise
new Promise(executer function)const lotteryPromise = new Promise(function (resolve, reject) {
console.log('Lottery draw is happening 💎');
setTimeout(function () {
if (Math.random() >= 0.5) {
resolve('You WIN 💰');
} else {
reject(new Error('You lost your money 💩'));
}
}, 2000);
});
lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
別の例-settimeout premizationconst wait = function (seconds) {
return new Promise(function (resolve) {
setTimeout(resolve, seconds * 1000);
});
};
wait(2)
.then(() => {
console.log('1 second passed');
return wait(1);
})
.then(() => {
console.log('2 second passed');
return wait(1);
})
.then(() => {
console.log('3 second passed');
return wait(1);
})
.then(() => {
console.log('4 second passed');
return wait(1);
});
콜백지옥과 비교
setTimeout(() => {
console.log('1 second passed');
setTimeout(() => {
console.log('2 seconds passed');
setTimeout(() => {
console.log('3 seconds passed');
}, 1000);
setTimeout(() => {
console.log('4 seconds passed');
}, 1000);
}, 1000);
}, 1000);
Promise resolveと拒否関数の作成と実行Promise.resolve('abc').then(x => console.log(x));
Promise.reject(new Error('Problem!')).catch(x => console.error(x));
Promisifying the Geolocation API const getPosition = function () {
return new Promise(function (resolve, reject) {
// navigator.geolocation.getCurrentPosition(
// position => resolve(position),
// err => reject(err)
// );
navigator.geolocation.getCurrentPosition(resolve, reject);
});
};
getPosition()
.then(pos => console.log(pos))
.catch(err => console.error(err));
const whereAmI = function () {
getPosition()
.then(pos => {
const { latitude: lat, longitude: lng } = pos.coords;
return fetch(`https://geocode.xyz/${lat},${lng}?geoit=json`);
})
.then(response => {
if (!response.ok)
throw new Error(`Problem with geocoding ${response.status}`);
return response.json();
})
.then(data => {
//console.log(data);
const { region, country } = data;
console.log(`You are in ${region}`);
return fetch(`https://restcountries.com/v2/name/${country}`);
})
.then(response => {
if (!response.ok)
throw new Error(`Country not found (${response.status})`);
return response.json();
})
.then(data => renderCountry(data[0]))
.catch(err => console.error(`${err.message} 💥`));
};
Reference
この問題について([JS]非同期-Promiseとfetch API,Event Loop), 我々は、より多くの情報をここで見つけました
https://velog.io/@hoje15v/비동기-Promise-Event-Loop
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
const lotteryPromise = new Promise(function (resolve, reject) {
console.log('Lottery draw is happening 💎');
setTimeout(function () {
if (Math.random() >= 0.5) {
resolve('You WIN 💰');
} else {
reject(new Error('You lost your money 💩'));
}
}, 2000);
});
lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
const wait = function (seconds) {
return new Promise(function (resolve) {
setTimeout(resolve, seconds * 1000);
});
};
wait(2)
.then(() => {
console.log('1 second passed');
return wait(1);
})
.then(() => {
console.log('2 second passed');
return wait(1);
})
.then(() => {
console.log('3 second passed');
return wait(1);
})
.then(() => {
console.log('4 second passed');
return wait(1);
});
콜백지옥과 비교
setTimeout(() => {
console.log('1 second passed');
setTimeout(() => {
console.log('2 seconds passed');
setTimeout(() => {
console.log('3 seconds passed');
}, 1000);
setTimeout(() => {
console.log('4 seconds passed');
}, 1000);
}, 1000);
}, 1000);
Promise.resolve('abc').then(x => console.log(x));
Promise.reject(new Error('Problem!')).catch(x => console.error(x));
const getPosition = function () {
return new Promise(function (resolve, reject) {
// navigator.geolocation.getCurrentPosition(
// position => resolve(position),
// err => reject(err)
// );
navigator.geolocation.getCurrentPosition(resolve, reject);
});
};
getPosition()
.then(pos => console.log(pos))
.catch(err => console.error(err));
const whereAmI = function () {
getPosition()
.then(pos => {
const { latitude: lat, longitude: lng } = pos.coords;
return fetch(`https://geocode.xyz/${lat},${lng}?geoit=json`);
})
.then(response => {
if (!response.ok)
throw new Error(`Problem with geocoding ${response.status}`);
return response.json();
})
.then(data => {
//console.log(data);
const { region, country } = data;
console.log(`You are in ${region}`);
return fetch(`https://restcountries.com/v2/name/${country}`);
})
.then(response => {
if (!response.ok)
throw new Error(`Country not found (${response.status})`);
return response.json();
})
.then(data => renderCountry(data[0]))
.catch(err => console.error(`${err.message} 💥`));
};
Reference
この問題について([JS]非同期-Promiseとfetch API,Event Loop), 我々は、より多くの情報をここで見つけました https://velog.io/@hoje15v/비동기-Promise-Event-Loopテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol