1. 使用 Promise.race()
处理超时Promise
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <title>promise-ajax</title> </head> <body> <script type="text/javascript">// Create a timeout promise function timeoutPromise(ms) {return new Promise((_, reject) => {setTimeout(() => reject(new Error('Request timeout')), ms);}); }// Fetch with timeout using Promise.race async function fetchDataWithTimeout(url, timeout = 5000) {try {const response = await Promise.race([fetch(url),timeoutPromise(timeout)]);if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const data = await response.text();return data;} catch (error) {console.error('Fetch error:', error);throw error;} }// Usage async function useWithTimeout() {try {const url = 'http://localhost:30000/test/slow';const result = await fetchDataWithTimeout(url, 3000); // 3 second timeoutconsole.log('Result:', result);} catch (error) {if (error.message === 'Request timeout') {console.error('Request timed out!');} else {console.error('Other error:', error);}} }useWithTimeout();</script></body> </html>
以上代码,设置超时时间为3秒,请求后3秒没有收到接口响应结果,就会结束请求。
2.使用 AbortController终止promise请求
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <title>promise-ajax</title> </head> <body> <script type="text/javascript">async function fetchDataWithAbort(url, timeout = 5000) {const controller = new AbortController();const timeoutId = setTimeout(() => controller.abort(), timeout);try {const response = await fetch(url, {signal: controller.signal});clearTimeout(timeoutId);if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const data = await response.text();return data;} catch (error) {clearTimeout(timeoutId);if (error.name === 'AbortError') {throw new Error('Request timeout');}console.error('Fetch error:', error);throw error;} }// Usage async function useWithAbort() {try {const url = 'http://localhost:30000/test/slow';const result = await fetchDataWithAbort(url, 3000); // 3 second timeoutconsole.log('Result:', result);} catch (error) {if (error.message === 'Request timeout') {console.error('Request timed out!');} else {console.error('Other error:', error);}} }useWithAbort();</script></body> </html>
同理,设置超时时间为3秒,请求后3秒没有收到接口响应结果,就会结束请求。
3.使用超时和重试次数来处理
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <title>promise-ajax</title> </head> <body> <script type="text/javascript">// Async function that returns a value async function fetchWithRetryAndTimeout(url, options = {}) {const { timeout = 5000, retries = 3, retryDelay = 1000 } = options;for (let i = 0; i <= retries; i++) {try {const controller = new AbortController();const timeoutId = setTimeout(() => controller.abort(), timeout);try {const response = await fetch(url, {signal: controller.signal,...options});clearTimeout(timeoutId);if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const data = await response.text();return data;} catch (error) {clearTimeout(timeoutId);if (error.name === 'AbortError') {throw new Error('Request timeout');}throw error;}} catch (error) {console.log(`Attempt ${i + 1} failed:`, error.message);if (i === retries) {throw new Error(`Failed after ${retries + 1} attempts: ${error.message}`);}// Wait before retryingawait new Promise(resolve => setTimeout(resolve, retryDelay));}} }// Usage async function useWithRetry() {try {const url = 'http://localhost:30000/test/slow';const result = await fetchWithRetryAndTimeout(url, {timeout: 3000,retries: 3,retryDelay: 1000});console.log('Result:', result);} catch (error) {console.error('Final error:', error.message);} }useWithRetry(); </script></body> </html>
以上代码,设置超时时间为3秒,请求间隔为1s,第一次请求失败后重试3次,如果重试3次后依然识别,就会结束请求。