Async/await في TypeScript

Async/await في TypeScript

تشرح هذه المقالة async/await في TypeScript۔

YouTube Video

Async/await في TypeScript

في TypeScript، تُستخدم الكلمة المفتاحية async لوصف العمليات غير المتزامنة بشكل مختصر، وتتصرف بشكل مشابه لصيغة JavaScript مع async/await.۔ تم تصميم الدوال async لجعل التعامل مع الدوال التي تُرجع Promises أكثر وضوحاً وبساطة.۔

أساسيات الدوال async

الدوال التي تُعرّف باستخدام الكلمة المفتاحية async تُرجع دائماً كائناً من نوع Promise.۔ إليك مثال بسيط:۔

1async function fetchData(): Promise<string> {
2    return "Data received";
3}
4
5fetchData().then((data) => console.log(data)); // "Data received"

في هذا المثال، بما أن الدالة async تُرجع دائماً كائناً من نوع Promise، يتم حل القيمة المُرجعة تلقائياً باستخدام Promise.resolve.۔ بعبارة أخرى، فإن "Data received" ستصبح كائناً من نوع Promise<string> ويتم التعامل معها كعملية غير متزامنة.۔

الكلمة المفتاحية await

يمكن استخدام الكلمة المفتاحية await فقط داخل دالة async.۔ يتيح ذلك إمكانية التوقف والانتظار للحصول على نتيجة كائن Promise قبل متابعة تنفيذ الدالة.۔

في المثال التالي، تمت كتابة معالجة غير متزامنة باستخدام fetch مع async/await

 1async function getUserData() {
 2    try {
 3        const response = await fetch("https://codesparklab.com/json/example.json");
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error("Error fetching user data:", error);
 8    }
 9}
10
11getUserData();

في هذا المثال، يتم استخدام await للانتظار حتى تكتمل عملية الـPromise التي تُرجعها دالة fetch، ويتم تخزين نتيجتها في المتغير response.۔ علاوة على ذلك، يتم أيضاً انتظار نتيجة response.json()

معالجة الأخطاء باستخدام async/await

يمكن التقاط الأخطاء التي تحدث أثناء المعالجة غير المتزامنة باستخدام بنية try...catch القياسية.۔ إذا حدث خطأ في جزء await، يتم معالجة هذا الخطأ في كتلة catch

 1async function fetchDataWithErrorHandling() {
 2    try {
 3        const response = await fetch('https://invalid.codesparklab.com/');
 4        if (!response.ok) {
 5            throw new Error(`HTTP error! status: ${response.status}`);
 6        }
 7        const data = await response.json();
 8        console.log(data);
 9    } catch (error) {
10        console.error("Fetch error:", error);
11    }
12}
13
14fetchDataWithErrorHandling();

في المثال أعلاه، يتم انتظار نتيجة دالة fetch باستخدام await، وإذا حدث خطأ يتم التعامل معه باستخدام try...catch

مزايا async/await

  1. معالجة غير متزامنة بديهية: باستخدام async/await تصبح تدفقات الكود أكثر بديهية مقارنة باستخدام سلاسل الكائنات Promise (مثل then أو catch)، مما يسمح بكتابتها كأنها معالجة متزامنة.۔

  2. معالجة الأخطاء بسهولة: استخدام try...catch يبسط عملية معالجة الأخطاء في العمليات غير المتزامنة.۔ يمكنك كتابة تعليمات برمجية أكثر قابلية للفهم مقارنة باستخدام سلاسل الكائنات Promise

القيم التي تُرجعها الدوال async

دالة async تعيد دائمًا كائنًا من نوع Promise۔ لذلك، حتى بدون إعادة كائن Promise صراحةً، يمكن إجراء المعالجة غير المتزامنة باستخدام الكلمة المفتاحية async۔

1async function example() {
2    return 42;
3}
4
5example().then((result) => console.log(result)); // 42

في الكود أعلاه، يتم إرجاع القيمة المتزامنة 42، ولكن نظرًا لأنها داخل دالة async، يتم تحويلها تلقائيًا إلى Promise.resolve(42)۔

التنفيذ التسلسلي للدوال غير المتزامنة

عند تنفيذ عدة دوال غير متزامنة بالتتابع، يمكنك استخدام await للتحكم في ترتيبها۔

 1async function fetchData(url: string): Promise<any> {
 2    try {
 3        const response = await fetch(url);
 4        return await response.json();
 5    } catch (error) {
 6        console.error("Error fetching user data:", error);
 7    }
 8}
 9
10async function fetchData1(): Promise<any> {
11    return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15    return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function processData() {
19    const data1 = await fetchData1();
20    console.log(data1);
21
22    const data2 = await fetchData2();
23    console.log(data2);
24}
25
26processData();

في هذا المثال، يتم تنفيذ fetchData2 بعد الانتظار حتى ينتهي fetchData1۔ هذا أكثر وضوحًا بالمقارنة مع استخدام سلسلة Promise۔

التنفيذ المتوازي

إذا كنت ترغب في تنفيذ العمليات غير المتزامنة بالتوازي، يمكنك استخدام Promise.all لمعالجة عدة كائنات Promises في آنٍ واحد۔

 1async function fetchData(url: string): Promise<any> {
 2    try {
 3        const response = await fetch(url);
 4        return await response.json();
 5    } catch (error) {
 6        console.error("Error fetching user data:", error);
 7    }
 8}
 9
10async function fetchData1(): Promise<any> {
11    return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15    return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function fetchMultipleData() {
19    const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
20    console.log(data1);
21    console.log(data2);
22}
23
24fetchMultipleData();

في هذه الحالة، يتم تنفيذ fetchData1 وfetchData2 في نفس الوقت، وتستمر العملية بعد إتمامهما۔ هذا يسمح بمعالجة فعالة للعديد من العمليات غير المتزامنة۔

الملخص

  • دالة async تُعيد كائن Promise، وباستخدام الكلمة المفتاحية await، يمكنك الانتظار لنتيجة العملية غير المتزامنة۔
  • باستخدام try...catch، يصبح التعامل مع الأخطاء في العمليات غير المتزامنة أبسط۔
  • باستخدام Promise.all، يمكن تنفيذ عدة عمليات غير متزامنة بالتوازي۔

async/await يُستخدم بشكل واسع في TypeScript وJavaScript لأنه يسمح بوصف أبسط للعمليات غير المتزامنة۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video