我在一组网址上寻找最佳网址(比如本地缓存):[' https://1.2.3.4',' https://httpbin.org/delay/3& #39;,' https://httpbin.org/status/500']并选择最佳工作时间超过5秒。否则后退到https://httpbin.org/status/200'。在这个人为的例子中,' https://httpbin.org/delay/3'应该赢!
function fallback(response) {
if (response.ok) {
return response;
}
console.log("Trying fallback")
return fetch("https://httpstat.us/200") // absolute fallback
}
var p = Promise.race([
fetch('https://1.2.3.4'), // will fail
fetch('https://httpbin.org/delay/3'), // should be the winner
fetch('https://httpbin.org/status/500'), // will fail
new Promise(function(resolve, reject) { // Competing with a timeout
setTimeout(() => reject(new Error('request timeout')), 5000)
})
])
.then(fallback, fallback)
.then(console.log)

我的代码存在问题,Promise race在任何返回时结束。我怎样才能最好地构建这一点,以便https://httpbin.org/delay/3'会正确赢得比赛吗?
答案 0 :(得分:0)
Promise.race([
new Promise(resolve => {
const ignoreError = () => {}
// first to resolve with .ok gets to resolve the promise
const resolveIfOk = res => res.ok && resolve(res)
fetch('https://httpbin.org/delay/20').then(resolveIfOk, ignoreError)
fetch('https://httpbin.org/delay/3').then(resolveIfOk, ignoreError)
fetch('https://1.2.3.4').then(resolveIfOk, ignoreError)
return;
}),
new Promise((_, reject) => setTimeout(() => reject(new Error('timed out')), 4000)) // reject if timeout
]).then(function(value) {
console.log("Success", value);
return value
}, function(reason) {
console.log("Going to use fallback", reason);
return fetch('https://httpstat.us/200')
}).then(console.log)
答案 1 :(得分:-1)
function race(promises) {
return Promise.race(Object.keys(promises).map((key) => {
return promises[key]
}))
.then(function(response) {
console.log(response);
if (!response.ok) {
delete promises[response.url];
return race(promises)
} else if (Object.keys(promises).length == 0 || response.url == 'timeout') {
console.log('returning default');
return fetch("https://httpstat.us/200")
}
return response;
})
}
race({
'https://1.2.3.4': fetch('https://1.2.3.4'),
'https://1.2.3.4': fetch('https://1.2.3.4'),
'timeout': new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
}).then(function(response) {
console.log(response)
}).catch(function(err) {
console.log('err:');
console.log(err.message)
return fetch("https://httpstat.us/200")
}).then(function(defaultFetch) {
console.log('timed out requesting failed urls, getting default:');
console.log(defaultFetch);
});