mirror of
https://github.com/axios/axios.git
synced 2026-04-11 02:11:50 +08:00
docs: add abort controller example (#7287)
Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
parent
bf3f63237c
commit
38be3b2e18
132
examples/abort-controller/index.html
Normal file
132
examples/abort-controller/index.html
Normal file
@ -0,0 +1,132 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>axios - abort controller example</title>
|
||||
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/>
|
||||
<style>
|
||||
.status { margin-top: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="container">
|
||||
<h1>axios.AbortController</h1>
|
||||
|
||||
<div class="row" style="margin-top: 20px;">
|
||||
<div class="col-md-12">
|
||||
<h3>1. Single Request Cancellation</h3>
|
||||
<p>Click "Start Request" to begin a 3-second request. Click "Cancel Request" to abort it.</p>
|
||||
<button id="startBtn" class="btn btn-primary">Start Request</button>
|
||||
<button id="cancelBtn" class="btn btn-danger" disabled>Cancel Request</button>
|
||||
<div id="singleStatus" class="status"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="row" style="margin-top: 20px;">
|
||||
<div class="col-md-12">
|
||||
<h3>2. Search-as-you-type (Race Condition Handling)</h3>
|
||||
<p>Type quickly. Previous pending requests will be cancelled automatically.</p>
|
||||
<div class="form-group">
|
||||
<input type="text" id="searchInput" class="form-control" placeholder="Type to search...">
|
||||
</div>
|
||||
<div id="searchStatus" class="status"></div>
|
||||
<ul id="searchLog" class="list-group" style="margin-top: 10px; max-height: 200px; overflow-y: auto;"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/axios.min.js"></script>
|
||||
<script>
|
||||
// -----------------------------------------------------------------------
|
||||
// 1. Single Request Cancellation
|
||||
// -----------------------------------------------------------------------
|
||||
const startBtn = document.getElementById('startBtn');
|
||||
const cancelBtn = document.getElementById('cancelBtn');
|
||||
const singleStatus = document.getElementById('singleStatus');
|
||||
|
||||
let controller;
|
||||
|
||||
startBtn.onclick = function() {
|
||||
// Create a new AbortController instance for this request
|
||||
controller = new AbortController();
|
||||
|
||||
startBtn.disabled = true;
|
||||
cancelBtn.disabled = false;
|
||||
singleStatus.innerHTML = '<span class="text-info">Request pending... (3s delay)</span>';
|
||||
|
||||
axios.get('/abort-controller/server?delay=3000', {
|
||||
signal: controller.signal
|
||||
})
|
||||
.then(function (response) {
|
||||
singleStatus.innerHTML = '<span class="text-success">' + response.data.message + '</span>';
|
||||
})
|
||||
.catch(function (err) {
|
||||
if (axios.isCancel(err)) {
|
||||
singleStatus.innerHTML = '<span class="text-warning">Request canceled: ' + err.message + '</span>';
|
||||
} else {
|
||||
singleStatus.innerHTML = '<span class="text-danger">Error: ' + err.message + '</span>';
|
||||
}
|
||||
})
|
||||
.finally(function () {
|
||||
startBtn.disabled = false;
|
||||
cancelBtn.disabled = true;
|
||||
controller = null;
|
||||
});
|
||||
};
|
||||
|
||||
cancelBtn.onclick = function() {
|
||||
if (controller) {
|
||||
// Abort the request
|
||||
controller.abort();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 2. Search-as-you-type
|
||||
// -----------------------------------------------------------------------
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
const searchStatus = document.getElementById('searchStatus');
|
||||
const searchLog = document.getElementById('searchLog');
|
||||
|
||||
let searchController;
|
||||
|
||||
searchInput.addEventListener('input', function(e) {
|
||||
const query = e.target.value;
|
||||
|
||||
if (searchController) {
|
||||
// Cancel the previous request
|
||||
searchController.abort();
|
||||
}
|
||||
|
||||
// Create a new controller for the new request
|
||||
searchController = new AbortController();
|
||||
|
||||
log('New search for: "' + query + '"');
|
||||
searchStatus.innerHTML = '<span class="text-info">Searching...</span>';
|
||||
|
||||
axios.get('/abort-controller/server?delay=1000', {
|
||||
signal: searchController.signal
|
||||
})
|
||||
.then(function (response) {
|
||||
searchStatus.innerHTML = '<span class="text-success">Result for "' + query + '": ' + response.data.message + '</span>';
|
||||
log('Success: ' + query);
|
||||
})
|
||||
.catch(function (err) {
|
||||
if (axios.isCancel(err)) {
|
||||
log('Cancelled: ' + query);
|
||||
} else {
|
||||
searchStatus.innerHTML = '<span class="text-danger">Error: ' + err.message + '</span>';
|
||||
log('Error: ' + query);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function log(msg) {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'list-group-item py-1';
|
||||
li.textContent = new Date().toLocaleTimeString() + ' - ' + msg;
|
||||
searchLog.prepend(li);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
16
examples/abort-controller/server.js
Normal file
16
examples/abort-controller/server.js
Normal file
@ -0,0 +1,16 @@
|
||||
import url from 'url';
|
||||
|
||||
export default function (req, res) {
|
||||
const parsedUrl = url.parse(req.url, true);
|
||||
const delay = parsedUrl.query.delay || 3000;
|
||||
|
||||
setTimeout(() => {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/json'
|
||||
});
|
||||
res.write(JSON.stringify({
|
||||
message: 'Response completed successfully after ' + delay + 'ms'
|
||||
}));
|
||||
res.end();
|
||||
}, delay);
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user