将 Fetch API 与 Promise.all 结合使用

问题描述 投票:0回答:3

我的目标是从两个 URL 获取数据,并仅在两个 URL 均成功返回时才执行操作。另一方面,如果其中任何一个失败,我想返回错误。我已经尝试了我的代码并设法获得了所需的效果。

我的问题是,是否有更高效、更简洁的方法来实现相同的功能?

辅助功能

let status = (r) => {  
  if (r.ok) {  
    return Promise.resolve(r)  
  } else {  
    return Promise.reject(new Error(r.statusText))  
  }  
}

let json = (r) => r.json();

要求

let urls = [
    'http://localhost:3000/incomplete',
    'http://localhost:3000/complete'
]

let promises = urls.map(url => {

    return fetch(url)  
    .then(status)  
    .then(json)  
    .then(d => Promise.resolve(d))
    .catch(e => Promise.reject(new Error(e)));

});

Promise.all(promises).then(d => {
    // do stuff with d
}).catch(e => {
    console.log('Whoops something went wrong!', e);
});
javascript ajax ecmascript-6 es6-promise fetch-api
3个回答
5
投票

// https://jsonplaceholder.typicode.com - Provides test JSON data
var urls = [
  'https://jsonplaceholder.typicode.com/todos/1',
  'https://jsonplaceholder.typicode.com/todos/2',
  'https://jsonplaceholder.typicode.com/posts/1',
  'https://jsonplaceholder.typicode.com/posts/2'
];

// Maps each URL into a fetch() Promise
var requests = urls.map(function(url){
  return fetch(url)
  .then(function(response) {
    // throw "uh oh!";  - test a failure
    return response.json();
  })  
});

// Resolve all the promises
Promise.all(requests)
.then((results) => {
  console.log(JSON.stringify(results, null, 2));
}).catch(function(err) {
  console.log("returns just the 1st failure ...");
  console.log(err);
})
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>


3
投票
const urls = [
    'http://localhost:3000/incomplete',
    'http://localhost:3000/complete'
]
const json = (r) => r.json()
const status = (r) => r.ok ? Promise.resolve(r) : Promise.reject(new Error(r.statusText))
const toRequest = url => fetch(url).then(status).then(json)
const onError = e => { console.log('Whoops something went wrong!', e) }
const consumeData = data => { console.log('data: ', data) }

Promise.all(urls.map(toRequest))
  .then(consumeData)
  .catch(onError)

2
投票

使用 fetchOk 获得更好的错误消息,并使用 destructuring 访问结果:

let fetchOk = (...args) => fetch(...args)
  .then(res => res.ok ? res : res.json().then(data => {
    throw Object.assign(new Error(data.error_message), {name: res.statusText});
  }));

Promise.all([
  'http://localhost:3000/incomplete',
  'http://localhost:3000/complete'
].map(url => fetchOk(url).then(r => r.json()))).then(([d1, d2]) => {
  // do stuff with d1 and d2
}).catch(e => console.error(e));


// Work around stackoverflow's broken error logger.
var console = { error: msg => div.innerHTML += msg + "<br>" };
<div id="div" style="white-space: pre;"></div>

© www.soinside.com 2019 - 2024. All rights reserved.