использование fetch внутри другой выборки в javascript
Я хочу получить api и после этого позвонить другому. Это разумно использовать такой код в javascript?
fetch(url, {
method: 'get',
}).then(function(response) {
response.json().then(function(data) {
fetch(anotherUrl).then(function(response) {
return response.json();
}).catch(function() {
console.log("Booo");
});
});
})
.catch(function(error) {
console.log('Request failed', error)
});
Ответы
Ответ 1
Fetch возвращает обещание, и вы можете связать несколько обещаний и использовать результат первого запроса во втором запросе:
В этом примере используется API SpaceX, чтобы получить информацию о последнем запуске, найти идентификатор ракеты и получить информацию о ракетах.
var url = 'https://api.spacexdata.com/v2/launches/latest';
var result = fetch(url, {
method: 'get',
}).then(function(response) {
return response.json(); // pass the data as promise to next then block
}).then(function(data) {
var rocketId = data.rocket.rocket_id;
console.log(rocketId, '\n');
return fetch('https://api.spacexdata.com/v2/rockets/' + rocketId); // make a 2nd request and return a promise
})
.then(function(response) {
return response.json();
})
.catch(function(error) {
console.log('Request failed', error)
})
// I'm using the result variable to show that you can continue to extend the chain from the returned promise
result.then(function(r) {
console.log(r); // 2nd request result
});
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ 2
Нет проблем с вызовами вложенности fetch()
. Это зависит от того, чего вы пытаетесь достичь, вложенных вызовов.
Вы можете альтернативно использовать .then()
для цепочки вызовов. См. Также Как структурировать вложенные обещания
fetch(url)
.then(function(response) {
return response.json()
})
.then(function(data) {
// do stuff with 'data', call second 'fetch'
return fetch(data.anotherUrl)
})
.then(function(response) {
return response.json();
})
.then(function(data) {
// do stuff with 'data'
})
.catch(function(error) {
console.log('Requestfailed', error)
});
Ответ 3
Это общий вопрос, с которым люди сталкиваются, начиная с обещаний, включая меня, когда я начал. Однако сначала...
Замечательно, что вы пытаетесь использовать новый API Fetch, но если бы я был вами, я бы использовал реализацию XMLHttpRequest, например jQuery AJAX или Backbone, переопределенную реализацию jQuery .ajax()
, если вы уже используете эти библиотеки. Причина в том, что API-интерфейс Fetch все еще настолько новый и, следовательно, экспериментальный на этом этапе.
С учетом сказанного, люди определенно используют его, но я не буду в своем собственном коде производства, пока он не будет "экспериментальным".
Если вы решите продолжить использование fetch
, имеется полипол. ПРИМЕЧАНИЕ. Вам нужно перейти через дополнительные обручи, чтобы обеспечить правильную работу обработки ошибок и получать файлы cookie с сервера. Если вы уже загружаете jQuery или используете Backbone, просто держитесь за них; не так уж и страшно.
Теперь на код:
Вы хотите плоскую структуру, иначе вам не хватит точки обещаний. Неразумно вкладывать обещания, обязательно, потому что обещания решают, какие вложенные асинхронные обратные вызовы (callback hell) не могли.
Вы сэкономите время и энергию и получите меньше кода с ошибкой, просто используя более читаемую структуру кода. Это не все, но это часть игры, так сказать.
Обещания заключаются в том, что асинхронный код сохраняет большинство потерянных свойств синхронного кода, таких как плоский отступ и один канал исключения.
- Петька Антонов (библиотека обещаний Блюберд)
// run async #1
asyncGetFn()
// first 'then' - execute more async code as an arg, or just accept results
// and do some other ops
.then(response => {
// ...operate on response data...or pass data onto next promise, if needed
})
// run async #2
.then(asyncGetAnotherFn)
.then(response => {
// ...operate on response data...or pass data onto next promise, if needed
})
// flat promise chain, followed by 'catch'
// this is sexy error handling for every 'then' above
.catch(err => {
console.error('Request failed', err)
// ...raise exeption...
// ... or, retry promise...
})