การยกเลิกคำขอ JavaScript
สำหรับใครก็ตามที่ทำงานเชื่อมช่องว่างระหว่างแบ็กเอนด์หรือฝั่งเซิร์ฟเวอร์ของเว็บแอปพลิเคชันกับฟรอนต์เอนด์หรือฝั่งเบราว์เซอร์ของเว็บแอปพลิเคชัน ทราบดีว่ามีสองตัวเลือกยอดนิยมที่ทันสมัยสำหรับการโต้ตอบกับโปรโตคอลการตอบกลับคำขอ หรือที่รู้จักกันดีในชื่อ http(s)¹. ตัวเลือกหลักเหล่านั้นคือFetch API ² ซึ่งเป็นเมธอด JavaScript ในตัวแบบใหม่ที่สร้างขึ้นตามคำสัญญา และAxios APIซึ่งเป็นไลบรารีเสริมเสริมซึ่งอิงตามคำสัญญาเช่นกัน
มีการเปรียบเทียบและทำความเข้าใจมากมายระหว่างทั้งสองเมื่อเริ่มต้นโครงการใหม่เพื่อพิจารณาว่าโครงการใดเหมาะสมกับความต้องการของโครงการมากกว่า แต่นั่นจะไม่ใช่จุดเน้นในที่นี้ โปรเจ็กต์ที่ฉันกำลังทำอยู่นั้นรวมและใช้ Axios อยู่แล้ว ดังนั้นในขณะที่ฉันสามารถเลือกไลบรารีใดก็ได้สำหรับฉันที่ต้องการใช้ Axios
ฉันกำลังสร้างส่วนต่อประสานส่วนหน้าสำหรับผู้มีส่วนได้ส่วนเสียทางธุรกิจเพื่อสอบถามฐานข้อมูลของเราและดูผลลัพธ์ในตารางที่ออกแบบมาอย่างพิถีพิถัน เนื่องจากจำนวนและความซับซ้อนของการสืบค้น การร้องขอข้อมูลเหล่านี้อาจใช้เวลาหลายวินาทีในการเรียกใช้ นอกจากนี้ ยังมีหลายวิธีในการกรองและค้นหาข้อมูลที่จำเป็น ทำให้เกิดความเป็นไปได้ในการเริ่มการทำงานของคำขอหลายรายการ เนื่องจากมีการส่งคำขอใหม่ทุกครั้งที่ผู้ใช้ใช้ตัวกรองหรือคำค้นหาเพื่อสร้างคำขอใหม่ ดังนั้นความต้องการเริ่มต้นในการส่งคำขอและรับการตอบกลับจึงเป็นเรื่องง่ายที่จะแก้ไข อย่างไรก็ตาม ด้วยการใช้งานขั้นพื้นฐานนี้และความเป็นไปได้ของการใช้ตัวกรองหลายตัวซึ่งสร้างคำขอหลายรายการ ทำให้การแสดงข้อมูลที่ร้องขอล่าสุดล่าช้า
ตอนนี้ปัญหาได้กลายเป็นคำขอมากเกินไปและมีการตอบกลับที่ค้างส่งไปยัง UI ซึ่งไม่จำเป็นต้องแสดง ความต้องการแคบลงจนกลายเป็นวิธีการจำกัดคำขอหรือแสดงเฉพาะคำขอสุดท้าย เมื่อผู้ใช้ค้นหาและกรองการเลือกสำหรับการสืบค้นขั้นสูงเสร็จแล้ว ตกลงดังนั้นวิธีการใช้?
หนึ่งในความเป็นไปได้แรกๆ ที่นึกถึงคือการใช้ตัวฟังเหตุการณ์ในคอมโพเนนต์ UI เพื่อรอจนกว่าผู้ใช้จะเลือกตัวกรองและค้นหาเสร็จ เมื่อพิจารณาเพิ่มเติมแล้ว นี่เป็นแนวคิดที่ค่อนข้างไร้เดียงสา และการนำไปปฏิบัติก็มีความซับซ้อนโดยไม่จำเป็น มีคอมโพเนนต์ UI หลายอย่างที่ต้องฟัง และพยายามเดาว่าจะฟังส่วนไหน และต้องรออีกนานแค่ไหนหลังจากนั้นดูเหมือนจะเป็นไปไม่ได้ นอกจากนี้ยังไม่สามารถแก้ปัญหาการสืบค้นที่ใช้เวลานาน การสืบค้นที่ซับซ้อนยังคงต้องส่งคืนและแสดงผลก่อนที่จะทำการเลือกใหม่ ความเป็นไปได้อีกอย่างที่สมเหตุสมผลกว่าคือการหยุดการสืบค้นก่อนหน้าจากการตอบกลับให้เสร็จสิ้นและส่งคืนเฉพาะการสืบค้นปัจจุบันเท่านั้น เป็นไปได้ไหมและอย่างไร?
ปรากฎว่าเป็นไปได้ โดยยกเลิกคำขอ เนื่องจากสร้างด้วยสัญญา Javascript จึงเป็นไปได้ที่จะยกเลิกคำขอด้วยทั้ง Fetch และ Axios ปัญหานี้แก้ได้สนุกเพราะมีบทความไม่มากนัก ซึ่งแตกต่างจากหัวข้อยอดนิยมอื่นๆ นอกจากนี้ยังมีขอบเขตที่ดีและเอกสาร Axios ที่ยอดเยี่ยมนำไปสู่การทดสอบและการนำไปใช้อย่างรวดเร็ว ดังนั้น หากคุณสนใจวิธียกเลิกคำขอดึงข้อมูล โปรดดูบทความนี้หรือหากคุณสนใจวิธียกเลิกคำขอ Axios และวิธีดำเนินการ โปรดอ่านต่อ!
ข้อจำกัดความรับผิดชอบโดยย่อ: เดิมทีฉันพบปัญหานี้และเริ่มโครงร่างสำหรับสิ่งนี้มาระยะหนึ่งแล้ว และกำลังทำงานบน Axios v.0.21.1 ฉันเห็นว่าตั้งแต่นั้นมา ในเวอร์ชันรองที่ตามมา การนำไปใช้งานก็เปลี่ยนไป ซึ่งหมายความว่าได้เวลาสำหรับการรีแฟคเตอร์โบนัสในบทความอื่นแล้ว!
แต่ก่อนอื่น ฉันจะดำเนินการตามแนวทางสำหรับโซลูชันดั้งเดิม ตามที่ระบุไว้ก่อนหน้านี้ ฉันไม่พบบทความหรือวิธีการทีละขั้นตอนมากเกินไปในการดำเนินการยกเลิกคำขอ Axios อย่างไรก็ตาม ทีมงานมีเอกสารที่ยอดเยี่ยม ดังนั้น ฉันจึงทำการทดลองเล็กๆ น้อยๆ เพื่อทดสอบการยกเลิกคำขอของตัวเอง ซึ่งฉันจะทำหลังจากมีพื้นฐานเพิ่มเติมเล็กน้อย
สำหรับพื้นหลังเพิ่มเติมเกี่ยวกับโปรเจ็กต์ มันเป็นโปรเจ็กต์ดั้งเดิมของ Ruby on Rails ซึ่งค่อยๆ เปลี่ยนเป็น API ที่มีฟรอนต์เอนด์ React ดังนั้นเพื่อให้ง่ายต่อการพิสูจน์แนวคิดในการทดสอบ ก่อนอื่นฉันอยากลองใช้ Rails API แล้วจึงหาวิธีเสียบเข้ากับแอป React ที่เรากำหนดเอง
ข้อจำกัดความรับผิดชอบข้อที่ 2: ฉันชอบเรียนรู้สิ่งใหม่ๆ โดยการจับคู่กับผู้อื่น การหาคู่เป็นเรื่องสนุกมากขึ้น โดยเฉพาะอย่างยิ่งเมื่อเรียนรู้สิ่งใหม่ๆ มันง่ายมากที่จะจมและทำผิดพลาดหรือพลาดขั้นตอนง่ายๆ ซึ่งมีโอกาสน้อยกว่ามากที่จะเกิดขึ้นกับอีกคู่หนึ่ง! ดังนั้น ในบางจุดของกระบวนการแก้ปัญหานี้ "ฉัน" จึงกลายเป็น "เรา" ก่อนที่ฉันจะออกเดี่ยวอีกครั้ง และฉันขอแนะนำอย่างยิ่งให้แก้ไขปัญหานี้หรือสิ่งใหม่ๆ ร่วมกับเพื่อนเช่นกัน!
มันเป็นแบบนี้ — ในแอพ Rails ของเรา:
- เพิ่มมุมมองไปยังตัวควบคุม เราทราบดีว่าเราต้องการทดสอบคำขอหลายรายการที่ใช้เวลาต่างกันในการแก้ไข เพื่อดูว่าเราสามารถยกเลิกคำขอใดคำขอหนึ่งหรือทั้งสองอย่าง จากนั้นเราตั้งสมมติฐานว่าจะแสดงผลแบบใดและทดสอบว่าผลลัพธ์ใดแสดงผลจริง เราได้เพิ่มวิธีการจับเวลาเพื่อจำลองการตอบสนองที่ใช้เวลาในการคำนวณเพิ่มขึ้น
def lol
if params[:wat] == '1'
sleep 1
render json: '"one"'
else
render json: '"two"'
end
end
get '/lol', to: "view#lol"
const axios = require('axios');
const CancelToken = axios.CancelToken;
const source1 = CancelToken.source();
const source2 = CancelToken.source();
axios.get('http://localhost:3001/v0/lol?wat=1', {
// set the token
cancelToken: source1.token
}).then(response => {
// log response
console.log('response 1', response.data)
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
// log request if canceled
console.log('Request 1 canceled', thrown.message);
} else {
// handle error
console.log('failed 1', thrown)
}
});
// cancel the request with a message
source1.cancel('Operation canceled by the user.');
axios.get('http://localhost:3001/v0/lol?wat=2', {
cancelToken: source2.token
}).then(response => {
console.log('response 2', response.data)
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log('Request 2 canceled', thrown.message);
} else {
console.log('failed 2', thrown)
}
});
.catch(error => {
if (axios.isCancel(error)) {
// Cancel request without dispatching an actual error.
return;
}
}
export default async function request(
path,
method,
{ body, headers, baseUrl, params, withCredentials = true, cancelToken } = {}
) { .... }
const [cancelToken, setCancelToken] = useState();
const { data, isLoading, error, request } = usePromise(() => {
// For every new request made, the previous request is canceled.
cancelToken?.cancel('Newer request made.');
const tokenSource = axios.CancelToken.source();
setCancelToken(tokenSource);
return getRequest(filter, page, 20, tokenSource.token);
}, {
effectCondition: [page, filter],
isEffect: true,
});
โบนัส: รีแฟคเตอร์!
- 's' หมายถึงความปลอดภัย ปลอดภัยเนื่องจากข้อมูลที่ส่งไปมาในการเชื่อมต่อถูกเข้ารหัสสำหรับ https และเป็นข้อความธรรมดาผ่าน http เท่านั้น
- Fetch เป็นมาตรฐาน API ใหม่ที่สร้างขึ้นจากXMLHttpRequestซึ่ง Axios ก็ใช้อยู่เช่นกัน





































![รายการที่เชื่อมโยงคืออะไร? [ส่วนที่ 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)