Ars*_* S. 8 fetch react-native
我有一个正在运行的用户登录功能.但是,我想为fetch合并一个超时错误.有没有办法设置一个5秒左右的计时器,以便在这样的时间后停止尝试获取?否则,我只是在网络错误一段时间后得到一个红色屏幕.
_userLogin() {
var value = this.refs.form.getValue();
if (value) { // if validation fails, value will be null
if (!this.validateEmail(value.email)) {
Alert.alert(
"Enter a valid email",
)
} else {
fetch("http://51.64.34.134:5000/api/login", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
timeout: 5000,
body: JSON.stringify({
username: value.email,
password: value.password,
})
})
.then((response) => response.json())
.then((responseData) => {
if (responseData.status == "success") {
this._onValueChange(STORAGE_KEY, responseData.data.token)
Alert.alert(
"Login Success!",
)
this.props.navigator.push({ name: 'StartScreen'})
} else if (responseData.status == "error") {
Alert.alert(
"Login Error",
responseData.message
)
}
})
.done();
}
}},
Run Code Online (Sandbox Code Playgroud)
// Wrapper function for fetch
const fetchSomething = async () => {
let controller = new AbortController()
setTimeout(() => controller.abort(), 3000); // abort after 3 seconds
const resp = await fetch('some url', {signal: controller.signal});
const json = await resp.json();
if (!resp.ok) {
throw new Error(`HTTP error! status: ${resp.status}`);
}
return json;
}
// usage
try {
let jsonResp = await fetchSomthing();
console.log(jsonResp);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Network Error');
} else {
console.log(error.message);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为使用AbortController是中止呼叫的推荐方法fetch。上面的代码片段处理以下场景:
setTimeout将在三秒后AbortController触发中止。fetch将记录“网络错误”消息。AbortController使用中止的文档fetch在这里。
我制作了一个 ES6 函数,将 ES fetch 包装成一个 promise,这里是:
export async function fetchWithTimeout(url, options, timeout = 5000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
]);
}
Run Code Online (Sandbox Code Playgroud)
以下是如何使用它:
const requestInfo = {
method,
headers,
body,
};
const url = 'http://yoururl.edu.br'
let data = await fetchWithTimeout(url, requestInfo, 3000);
Run Code Online (Sandbox Code Playgroud)
没有标准的方法来处理这个问题,因为官方规范中尚未定义超时选项。定义了一个中止,您可以将其与您自己的超时和承诺结合使用。例如,如此处和此处所示。我已经复制了示例代码,但尚未亲自测试。
// Rough implementation. Untested.
function timeout(ms, promise) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error("timeout"))
}, ms)
promise.then(resolve, reject)
})
}
timeout(1000, fetch('/hello')).then(function(response) {
// process response
}).catch(function(error) {
// might be a timeout error
})
Run Code Online (Sandbox Code Playgroud)
另一种选择是自己修改 fetch.js 模块以添加调用 abort 的超时,如此处所示。
| 归档时间: |
|
| 查看次数: |
13134 次 |
| 最近记录: |