WithCancel وWithTimeout
إنشاء سياقات قابلة للإلغاء ومحددة بمهلة زمنية
WithCancel وWithTimeout درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.
context.WithCancel
يشتق WithCancel سياقًا جديدًا مع دالة إلغاء. يؤدي استدعاء cancel إلى إغلاق قناة Done في السياق المشتق وجميع أبنائه.
ctx, cancel := context.WithCancel(parent)
defer cancel() // always call to release resources
go doWork(ctx)استخدم defer cancel دائمًا
يؤدي عدم استدعاء cancel إلى تسريب goroutine التي تراقب السياق الأب. استخدم defer cancel مباشرةً بعد إنشاء سياق قابل للإلغاء دائمًا.
context.WithTimeout
يشتق WithTimeout سياقًا يُلغى تلقائيًا بعد المدة المحددة. وهو غلاف ملائم حول WithDeadline.
ctx, cancel := context.WithTimeout(parent, 5*time.Second)
defer cancel()
if err := db.QueryContext(ctx, query); err != nil {
// err may be context.DeadlineExceeded
}التحقق من Err()
بعد إغلاق Done، يعيد ctx.Err() السبب: context.Canceled (أُلغي صراحةً) أو context.DeadlineExceeded (انتهت المهلة).
if err := ctx.Err(); errors.Is(err, context.DeadlineExceeded) {
log.Println("timeout")
}الإلغاء من goroutine أخرى
يمكن استدعاء دالة الإلغاء بأمان من أي goroutine، ومن عدة goroutines بالتزامن. ولا يكون للاستدعاء الأول فقط أي تأثير إضافي.
ctx, cancel := context.WithCancel(context.Background())
go func() {
if detectError() { cancel() }
}()مهلة طلب HTTP
عيّن مهلة لكل طلب باستخدام WithTimeout على سياق الطلب الوارد:
func handler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel()
result, err := service.Call(ctx)
// ...
}الإلغاء المتسلسل
إذا أُلغي سياق أب، تُلغى تلقائيًا جميع السياقات المشتقة منه (الأبناء والأحفاد)، ما يوقف جميع goroutines في شجرة الاستدعاءات.
Context في الاختبارات
استخدم context.Background() أو context.WithTimeout في الاختبارات لضمان تقييد مدة goroutines التي تبدأها الاختبارات.
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
testResult := runTest(ctx)تمرير Context عبر المكتبات
مرّر دائمًا السياق الذي تلقيته إلى الاستدعاءات الصادرة (استعلامات قواعد البيانات واستدعاءات HTTP وRPCs). لا تهمله أو تستبدله مطلقًا، إلا إذا كان لديك سبب محدد لإعادة ضبط المهلة النهائية.
إنشاء سياق لمهمة في الخلفية
بالنسبة إلى المهام في الخلفية غير المرتبطة بطلب، استخدم context.Background() كجذر، وأضف WithCancel حتى تتمكن من إيقاف المهمة بسلاسة.
استخدام select مع Done
استخدم select دائمًا على ctx.Done() إلى جانب قناة العمل لتجنب الحجب عندما يُلغى السياق قبل اكتمال العمل.
select {
case result := <-workCh:
return result, nil
case <-ctx.Done():
return nil, ctx.Err()
}اختبار سريع
ما الفرق بين context.WithCancel وcontext.WithTimeout؟
مراجعة: WithCancel وWithTimeout
النقاط الأساسية:
- استخدم defer cancel() مباشرةً بعد الإنشاء دائمًا
- يلغي WithTimeout السياق تلقائيًا بعد مدة محددة؛ ويعيد DeadlineExceeded
- يميّز ctx.Err() بين Canceled وDeadlineExceeded
- ينتشر الإلغاء إلى جميع السياقات المشتقة
الأسئلة الشائعة
هل درس «WithCancel وWithTimeout» مجاني؟
نعم — نص درس «WithCancel وWithTimeout» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.
ماذا ستتعلم في «WithCancel وWithTimeout»؟
إنشاء سياقات قابلة للإلغاء ومحددة بمهلة زمنية تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟
لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «WithCancel وWithTimeout»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟
نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- لماذا يوجد context.Context؟
- WithCancel وWithTimeout
- WithDeadline وWithValue
- السياق في استدعاءات HTTP وقواعد البيانات