Мой первый вопрос: можем ли мы использовать ожидание для получения. то есть следующий фрагмент эквивалентен предоставленному им решению?
Нет. Когда в непосредственном теле функции asyn c, когда есть await
, функция будет полностью приостановлена, пока не выполнится следующее обещание. Таким образом, l oop
for(let name of names) {
let response
try {
response = await fetch(`https://api.github.com/users/${name}`);
} catch(e) {
response = null
}
нужно дождаться в последовательном , чтобы получить заголовки каждого ответа, прежде чем продолжать инициализацию следующего запроса.
Имеет ли он в виду, что если мы напишем решение таким образом
Во-первых, необходимо скорректировать синтаксис: .json
- это метод, поэтому его нужно вызывать:
async function getUser(name) {
const response = await fetch(`https://api.github.com/users/${name}`)
return response.ok ? await response.json() : null
// ^^
}
Но это прекрасно. Единственный await
в функции getUsers
ожидает разрешения целом Promise.all
; .map
пинг массива до вызова getUser
выполняется синхронно, поэтому все запросы отправляются одновременно, поэтому ни одному из сетевых запросов не нужно ждать, пока какой-либо другой запрос не завершится sh, чтобы работа.
Проблема, на которую ссылался автор, - вызывать Promise.all
для массива вызовов fetch
, а не для массива вызовов .json()
:
// Bad, do not use:
const getUsers = async (names) => {
const responses = await Promise.all(names.map(
name => fetch(`https://api.github.com/users/${name}`)
));
return Promise.all(responses.map(
response => response.ok ? response.json() : null
));
}
Проблема с вышесказанным заключается в том, что сценарий должен ожидать получения всех заголовков ответа от каждого запроса, прежде чем можно будет проанализировать тело ответа для любого из них.
Другое параллельное решение:
const getUsers = names => Promise.all(names.map(
async (name) => {
const res = await fetch(`https://api.github.com/users/${name}`);
return res.ok ? res.json() : null;
}
));