תכנות אסינכרוני הוא פרדיגמת תכנות שמאפשרת לך לכתוב קוד שרץ באופן אסינכרוני. להבדל מביצועי תכנות סינכרוני, שמבצע קוד בסדר רציף, תכנות אסינכרוני מאפשר לקוד לרוץ ברקע בזמן ששאר התוכנית ממשיכה להריץ. זה חשוב במיוחד למשימות שעשויות לדורש זמן רב להשלים, כגון גישה לנתונים מ-API מרוחק.
תכנות אסינכרוני
הוא חיוני ליצירת אפליקציות תגובתיות ויעילות ב-JavaScript. TypeScript, תת-סט של JavaScript, הופך את העבודה עם תכנות אסינכרוני לקלה יותר.
קיימות מספר גישות לתכנות אסינכרוני ב-TypeScript, כולל שימוש ב-promises
, async/await
, ו-callbacks
. נכסות כל אחת מהגישות הללו בפרט כדי שתוכל לבחור את הטובה ביותר עבור מקרה השימוש שלך.
טבלת תוכן
למה תכנות אסינכרוני חשוב?
תכנות אסינכרוני הוא חיוני לבניית יישומי אינטרנט מגיבים ויעילים. זה מאפשר למשימות לרוץ ברקע בזמן ששאר התוכנית ממשיכה, ושומר על ממשק המשתמש מגיב לקלט. בנוסף, תכנות אסינכרוני יכול לשפר את הביצועים הכוללים על ידי מתן אפשרות למספר משימות לפעול בו זמנית.
ישנם הרבה דוגמאות מהעולם האמיתי לתכנות אסינכרוני, כמו גישה למצלמות ומיקרופונים של משתמשים וטיפול באירועי קלט של משתמשים. גם אם אתה לא יוצר לעיתים קרובות פונקציות אסינכרוניות, חשוב לדעת כיצד להשתמש בהן בצורה נכונה כדי להבטיח שהיישום שלך מהימן ובעל ביצועים טובים.
כיצד TypeScript מקלה על תכנות אסינכרוני
TypeScript מציעה מספר תכונות שמפשטות את התכנות האסינכרוני, כולל בטיחות טיפוס
, חיזוי טיפוס
, בדיקת טיפוס
, והערות טיפוס
.
עם בטיחות טיפוס, אתה יכול להבטיח שהקוד שלך מתנהג כפי שמצופה, גם כאשר עובדים עם פונקציות אסינכרוניות. למשל, TypeScript יכולה לתפוס שגיאות הקשורות לערכים null ו-undefined בזמן ההידור, ולחסוך לך זמן ומאמץ בתיקון בעיות.
חיזוי הטיפוס ובדיקת הטיפוס של TypeScript גם מפחיתים את כמות הקוד הסטנדרטי שעליך לכתוב, מה שהופך את הקוד שלך ליותר תמציתי וקל לקריאה.
והערות הטיפוס של TypeScript מספקות בהירות ודוקומנטציה לקוד שלך, דבר שמועיל במיוחד כאשר עובדים עם פונקציות אסינכרוניות שעלולות להיות מורכבות להבנה.
עכשיו בואו נצלול ונלמד על שלוש התכונות המרכזיות של תכנות אסינכרוני: הבטחות, async/await, וקריאות חוזרות.
איך להשתמש בהבטחות ב-TypeScript
הבטחות הן כלי חזק לניהול פעולות אסינכרוניות ב-TypeScript. לדוגמה, ייתכן שתשתמש בהבטחה כדי למשוך נתונים מ-API חיצוני או לבצע משימה שדורשת זמן ברקע בזמן שה-thread הראשי שלך ממשיך לפעול.
כדי להשתמש בהבטחה, אתה יוצר מופע חדש של מחלקת Promise
ומעביר לה פונקציה שמבצעת את הפעולה האסינכרונית. פונקציה זו צריכה לקרוא למתודה resolve עם התוצאה כאשר הפעולה מצליחה או למתודה reject עם שגיאה אם היא נכשלת.
ברגע שההבטחה נוצרה, תוכל לחבר לה קריאות חוזרות באמצעות המתודה then
. קריאות חוזרות אלו יופעלו כאשר ההבטחה מתקיימת, עם הערך המתקבל מועבר כפרמטר. אם ההבטחה נדחית, תוכל לחבר מנהל שגיאות באמצעות המתודה catch, שתיקרא עם הסיבה לדחייה.
שימוש בהבטחות מציע מספר יתרונות על פני שיטות מבוססות קריאות חוזרות מסורתיות. לדוגמה, הבטחות יכולות לעזור למנוע "גיהינום קריאות חוזרות", בעיה נפוצה בקוד אסינכרוני שבה קריאות חוזרות מקוננות הופכות לקשות לקריאה ולתחזוקה.
הבטחות גם מקלות על ניהול שגיאות בקוד אסינכרוני, מכיוון שאתה יכול להשתמש במתודה catch כדי לנהל שגיאות שמתרחשות בכל מקום בשרשרת ההבטחה.
לבסוף, הבטחות יכולות לפשט את הקוד שלך על ידי מתן דרך עקבית, קומפוזיטיבית לנהל פעולות אסינכרוניות, ללא קשר ליישום הבסיסי שלהן.
איך ליצור הבטחה
סינתקס של הבטחה:
const myPromise = new Promise((resolve, reject) => {
// בצע פעולה אסינכרונית כלשהי
// אם הפעולה מצליחה, קרא resolve עם התוצאה
// אם הפעולה נכשלת, קרא reject עם אובייקט שגיאה
});
myPromise
.then((result) => {
// נהל את התוצאה המוצלחת
})
.catch((error) => {
// נהל את השגיאה
});
// דוגמה 1 על איך ליצור הבטחה
function myAsyncFunction(): Promise<string> {
return new Promise<string>((resolve, reject) => {
// פעולה אסינכרונית כלשהי
setTimeout(() => {
// פעולה מוצלחת פותרת את ההבטחה בדוק את הפוסט האחרון שלי בבלוג על שליטה בתכנות אסינכרוני בטייפסקריפט! למד איך לעבוד עם הבטחות, Async/Await ו-Callbacks כדי לכתוב קוד יעיל וניתן להרחבה. התכונן לקחת את כישורי הטייפסקריפט שלך לשלב הבא!
const success = true;
if (success) {
// פותר את ההבטחה עם תוצאת הפעולה אם הפעולה הייתה מוצלחת
resolve(
`The result is success and your operation result is ${operationResult}`
);
} else {
const rejectCode: number = 404;
const rejectMessage: string = `The result is failed and your operation result is ${rejectCode}`;
// דוחה את ההבטחה עם תוצאת הפעולה אם הפעולה נכשלת
reject(new Error(rejectMessage));
}
}, 2000);
});
}
// השתמש בהבטחה
myAsyncFunction()
.then((result) => {
console.log(result); // פלט: התוצאה היא הצלחה ותוצאת הפעולה שלך היא 4
})
.catch((error) => {
console.error(error); // פלט: התוצאה היא כישלון ותוצאת הפעולה שלך היא 404
});
בדוגמה שלמעלה, יש לנו פונקציה בשם myAsyncFunction()
שמחזירה promise
. אנו משתמשים בבנאי Promise
כדי ליצור את ה-promise, שמקבל פונקציית callback
עם ארגומנטים של resolve
ו־reject
. אם הפעולה האסינכרונית הצליחה, אנו קוראים לפונקצית ה־resolve. אם היא נכשלה, אנו קוראים לפונקצית ה־reject.
האובייקט ה-promise שמוחזר על ידי הבנאי כולל את השיטה then()
, שמקבלת פונקציות callback להצלחה ולכשלון. אם ה-promise נפתר בהצלחה, נקראת פונקציית ה-callback להצלחה עם התוצאה. אם ה-promise נדחה, נקראת פונקציית ה-callback לכשלון עם הודעת שגיאה.
לאובייקט ה-promise יש גם את השיטה catch()
שמשמשת לטיפול בשגיאות שנמצאות במהלך שרשרת ה-promise. השיטה catch()
מקבלת פונקציית callback שתקרא אם מתרחשת שגיאה במהלך שרשרת ה-promise.
עכשיו, בואו נמשיך לדבר על כיצד לשרשר promises ב-TypeScript.
כיצד לשרשר Promises
שרירות הרוח של promises מאפשרת לך לבצע פעולות אסינכרוניות מרובות
בסדר או בצמתות. זה מועיל כאשר אתה צריך לבצע מספר משימות אסינכרוניות אחת אחרי השנייה או באופן זמני. לדוגמה, יתכן ותצטרך לאחזר נתונים באופן אסינכרוני ולאחר מכן לעבד אותם באופן אסינכרוני.
בואו נסתכל על דוגמה של כיצד לשרשר promises:
// דוגמה על איך שרשור של promises עובד
// הבטחה הראשונה
const promise1 = new Promise((resolve, reject) => {
const functionOne: string = "This is the first promise function";
setTimeout(() => {
resolve(functionOne);
}, 1000);
});
// הבטחה השנייה
const promise2 = (data: number) => {
const functionTwo: string = "This is the second second promise function";
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(` ${data} '+' ${functionTwo} `);
}, 1000);
});
};
// שרשור של הבטחה הראשונה והשנייה
promise1
.then(promise2)
.then((result) => {
console.log(result); // פלט: זהו פונקציית הבטחה הראשונה + זהו פונקציית הבטחה השנייה השנייה
})
.catch((error) => {
console.error(error);
});
בדוגמה שמופיעה למעלה, יש לנו שתי promises: promise1
ו־promise2
. promise1
מבצעת פעולת resolve לאחר שנייה אחת ומחזירה את המחרוזת "זוהי פונקציית הבטחה הראשונה". promise2
מקבלת מספר כקלט ומחזירה promise שמבצעת resolve לאחר שנייה אחת ומחזירה מחרוזת המשלבת בינה לבין המספר שהתקבל והמחרוזת "זוהי פונקציית הבטחה השנייה".
אנו שרשורים את שתי הpromises ביחד באמצעות שימוש בשיטת then
. הפלט של promise1 מועבר כקלט ל־promise2. לבסוף, אנו משתמשים שוב בשיטת then
כדי להדפיס את הפלט של promise2
לקונסולה. אם פרסום אחד מבין promise1 או promise2 יכשל, השגיאה תיתפס על ידי שימוש בשיטת catch
.
מזל טוב! למדת כיצד ליצור ולרשרש promises ב־TypeScript. כעת, תוכל להשתמש בpromises כדי לבצע פעולות אסינכרוניות ב־TypeScript. כעת, נבדוק כיצד Async/Await
פועל ב־TypeScript.
כיצד להשתמש ב־Async / Await ב־TypeScript
אסינכרוני/ממתין הוא תחביר שהוצג ב-ES2017 כדי להקל על העבודה עם הבטחות. זה מאפשר לך לכתוב קוד אסינכרוני שנראה ומרגיש כמו קוד סינכרוני.
ב-TypeScript, אתה יכול להגדיר פונקציה אסינכרונית באמצעות המילה המפתח async
. זה אומר לקומפיילר שהפונקציה היא אסינכרונית ותחזיר הבטחה.
עכשיו, בואו נראה איך להשתמש באסינכרוני/ממתין ב-TypeScript.
תחביר אסינכרוני/ממתין:
// תחביר אסינכרוני/ממתין ב-TypeScript
async function functionName(): Promise<ReturnType> {
try {
const result = await promise;
// קוד לביצוע לאחר שההבטחה מתממשת
return result;
} catch (error) {
// קוד לביצוע אם ההבטחה נדחית
throw error;
}
}
בדוגמה למעלה, functionName
היא פונקציה אסינכרונית שמחזירה הבטחה של ReturnType
. המילה המפתח await
משמשת להמתין שההבטחה תתממש לפני שממשיכים לשורה הבאה של קוד.
הבלוק try/catch
משמש לטיפול בכל שגיאה שמתרחשת בזמן הרצת הקוד בתוך הפונקציה האסינכרונית. אם מתרחשת שגיאה, היא תיתפס על ידי הבלוק catch, שבו תוכל לטפל בה בצורה מתאימה.
שימוש בפונקציות חץ עם אסינכרוני/ממתין
אתה יכול גם להשתמש בפונקציות חץ עם תחביר אסינכרוני/ממתין ב-TypeScript:
const functionName = async (): Promise<ReturnType> => {
try {
const result = await promise;
// קוד לביצוע לאחר שההבטחה מתממשת
return result;
} catch (error) {
// קוד לביצוע אם ההבטחה נדחית
throw error;
}
};
בדוגמה למעלה, functionName
מוגדר כפונקציית חץ שמחזירה Promise של ReturnType
. המילה המפתח async מצביעה על כך שמדובר בפונקציה אסינכרונית, והמילה המפתח await משמשת להמתין שה-Promise יתממש לפני המעבר לשורה הבאה של הקוד.
אסינכרי / המתנה עם קריאת API
עכשיו, בואו נלך מעבר לסינטקס ונשיג נתונים מ-API באמצעות async/await.
interface User {
id: number;
name: string;
email: string;
}
const fetchApi = async (): Promise<void> => {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
if (!response.ok) {
throw new Error(
`Failed to fetch users (HTTP status code: ${response.status})`
);
}
const data: User[] = await response.json();
console.log(data);
} catch (error) {
console.error(error);
throw error;
}
};
fetchApi();
כאן, אנחנו משיגים נתונים מ-API של JSONPlaceholder, ממירים אותם ל-JSN, ואז רושמים אותם לקונסולה. זהו דוגמה מהעולם האמיתי כיצד להשתמש ב-async/await ב-TypeScript.
אתם אמורים לראות מידע על משתמשים בקונסולה. התמונה הזו מציגה את הפלט:
אסינכרי/המתנה עם קריאת API של Axios
// דוגמה 2 כיצד להשתמש ב-async / await ב-TypeScript
const fetchApi = async (): Promise<void> => {
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
const data = await response.data;
console.log(data);
} catch (error) {
console.error(error);
}
};
fetchApi();
בדוגמה למעלה, אנחנו מגדירים את הפונקציה fetchApi()
באמצעות async/await ואת השיטה Axios.get()
כדי לבצע בקשת HTTP GET לכתובת ה-URL המצוינת. אנחנו משתמשים ב-await כדי להמתין לתגובה, ואז שולפים את הנתונים באמצעות המאפיין data של אובייקט התגובה. לבסוף, אנחנו רושמים את הנתונים לקונסולה עם console.log()
. כל שגיאה שתתרחש תתפס ותרשם לקונסולה עם console.error()
.
אנו יכולים להשיג זאת באמצעות Axios, אז אתם אמורים לראות את אותו תוצאה בקונסולה.
התמונה הזו מציגה את הפלט כאשר משתמשים ב-Axios בקונסולה:
הערה: לפני שתנסו את הקוד למעלה, אתם צריכים להתקין את Axios באמצעות npm או yarn.
npm install axios
yarn add axios
אם אינך מוכר את Axios, תוכל ללמוד עוד על זה כאן.
ניתן לראות שהשתמשנו בבלוק try
ו-catch
כדי לטפל בשגיאות. הבלוק try
ו-catch
הוא שיטה לניהול שגיאות ב TypeScript. לכן, כאשר אתה עושה קריאות לAPI כמו שעשינו עכשיו, וודא שאתה משתמש בבלוק try
ו-catch
כדי לטפל בכל שגיאות.
עכשיו, בוא נבדוק שימוש מתקדם יותר של הבלוק try
ו-catch
ב TypeScript:
// דוגמה 3 על שימוש ב async / await ב TypeScript
interface Recipe {
id: number;
name: string;
ingredients: string[];
instructions: string[];
prepTimeMinutes: number;
cookTimeMinutes: number;
servings: number;
difficulty: string;
cuisine: string;
caloriesPerServing: number;
tags: string[];
userId: number;
image: string;
rating: number;
reviewCount: number;
mealType: string[];
}
const fetchRecipes = async (): Promise<Recipe[] | string> => {
const api = "https://dummyjson.com/recipes";
try {
const response = await fetch(api);
if (!response.ok) {
throw new Error(`Failed to fetch recipes: ${response.statusText}`);
}
const { recipes } = await response.json();
return recipes; // מחזיר את מערך המתכונים
} catch (error) {
console.error("Error fetching recipes:", error);
if (error instanceof Error) {
return error.message;
}
return "An unknown error occurred.";
}
};
// גישה והדפסת מתכונים
fetchRecipes().then((data) => {
if (Array.isArray(data)) {
console.log("Recipes fetched successfully:", data);
} else {
console.error("Error message:", data);
}
});
בדוגמה לעיל, אנו מגדירים interface Recipe
שמתאר את מבנה המידע שאנו מצפים לקבל מהAPI. לאחר מכן אנו יוצרים את הפונקציה fetchRecipes()
בשימוש ב async/await ובשיטת fetch() כדי לבצע בקשת HTTP GET לנקודת הקצה המסוימת של הAPI.
אנו משתמשים בבלוק try/catch
כדי לטפל בכל שגיאות שעשויות להתרחש במהלך הבקשה לAPI. אם הבקשה מוצלחת, אנו מחלץ את המאפיין data מהתגובה באמצעות await ומחזירים אותו. אם מתרחשת שגיאה, אנו בודקים אם קיים הודעת שגיאה ומחזירים אותה כמחרוזת אם היא קיימת.
לבסוף, אנו קוראים לפונקציה fetchRecipes()
ומשתמשים ב-.then()
כדי להדפיס את הנתונים שהוחזרו לקונסול. דוגמה זו מדגימה איך להשתמש ב-async/await
עם בלוקי try/catch
כדי לטפל בשגיאות בתרחיש מתקדם יותר, כאשר נדרש לחלץ נתונים מאובייקט תגובה ולהחזיר הודעת שגיאה מותאמת.
התמונה הבאה מציגה את תוצאת הפלט של הקוד:
Async / Await עם Promise.all
Promise.all()
היא שיטה שמקבלת מערך של promises כקלט (iterable) ומחזירה Promise יחיד כפלט. ה-Promise הזה נפתר כאשר כל ה-promises בקלט נפתרים או אם ה-iterable בקלט לא מכיל promises. הוא יסרב מיד אם אחד מה-promises בקלט נסרב או אם ישנן שגיאות בלתי-promises, והוא יסרב עם ההודעה או השגיאה הראשונה.
// דוגמה לשימוש ב-async / await עם Promise.all
interface User {
id: number;
name: string;
email: string;
profilePicture: string;
}
interface Post {
id: number;
title: string;
body: string;
}
interface Comment {
id: number;
postId: number;
name: string;
email: string;
body: string;
}
const fetchApi = async <T>(url: string): Promise<T> => {
try {
const response = await fetch(url);
if (response.ok) {
const data = await response.json();
return data;
} else {
throw new Error(`Network response was not ok for ${url}`);
}
} catch (error) {
console.error(error);
throw new Error(`Error fetching data from ${url}`);
}
};
const fetchAllApis = async (): Promise<[User[], Post[], Comment[]]> => {
try {
const [users, posts, comments] = await Promise.all([
fetchApi<User[]>("https://jsonplaceholder.typicode.com/users"),
fetchApi<Post[]>("https://jsonplaceholder.typicode.com/posts"),
fetchApi<Comment[]>("https://jsonplaceholder.typicode.com/comments"),
]);
return [users, posts, comments];
} catch (error) {
console.error(error);
throw new Error("Error fetching data from one or more APIs");
}
};
fetchAllApis()
.then(([users, posts, comments]) => {
console.log("Users: ", users);
console.log("Posts: ", posts);
console.log("Comments: ", comments);
})
.catch((error) => console.error(error));
בקוד לעיל, השתמשנו ב-Promise.all
כדי לקבל ערכי API מרובים בו זמנית. אם יש לך מספר APIים לקבל, תוכל להשתמש ב-Promise.all
כדי לקבל אותם כולם פעם אחת. כפי שניתן לראות, השתמשנו ב-map
כדי לעבור על מערך של APIים ולאחר מכן להעביר אותו ל-Promise.all
כדי לקבל אותם באופן סימולטני.
התמונה למטה מציגה את הפלט משיחות ה-API:
בואו נראה כיצד להשתמש ב-Promise.all
עם Axios:
// דוגמה לשימוש ב-async / await עם axios ו-Promise.all
const fetchApi = async () => {
try {
const urls = [
"https://jsonplaceholder.typicode.com/users",
"https://jsonplaceholder.typicode.com/posts",
];
const responses = await Promise.all(urls.map((url) => axios.get(url)));
const data = await Promise.all(responses.map((response) => response.data));
console.log(data);
} catch (error) {
console.error(error);
}
};
fetchApi();
בדוגמה לעיל, אנו משתמשים ב־Promise.all
כדי לקבל נתונים משני כתובות URL שונות באותו זמן. תחילה, אנו יוצרים מערך של כתובות URL, ואז משתמשים ב־map כדי ליצור מערך של Promises משאילתות axios.get
. אנו מעבירים את המערך הזה ל־Promise.all
, שמחזיר מערך של תגובות. לבסוף, אנו משתמשים שוב ב־map כדי לקבל את הנתונים מכל תגובה ולהדפיס אותם לקונסול.
איך להשתמש ב־Callbacks ב־TypeScript
Callback הוא פונקציה שמועברת כארגומנט לפונקציה אחרת. הפונקציה callback מתבצעת בתוך הפונקציה האחרת. Callbacks מבטיחים שפונקציה לא תרוץ לפני שהמשימה הושלמה – אבל תרוץ מיד לאחר סיום המשימה. הם עוזרים לנו לכתוב קוד JavaScript אסינכרוני ולמנוע בעיות ושגיאות.
// דוגמה לשימוש ב־callbacks ב־typescript
const add = (a: number, b: number, callback: (result: number) => void) => {
const result = a + b;
callback(result);
};
add(10, 20, (result) => {
console.log(result);
});
התמונה למטה מראה על הפונקציה callback:
בואו נראה דוגמה נוספת לשימוש ב־callbacks ב־TypeScript:
// דוגמה לשימוש בפונקציית callback ב־TypeScript
type User = {
name: string;
email: string;
};
const fetchUserData = (
id: number,
callback: (error: Error | null, user: User | null) => void
) => {
const api = `https://jsonplaceholder.typicode.com/users/${id}`;
fetch(api)
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error("Network response was not ok.");
}
})
.then((data) => {
const user: User = {
name: data.name,
email: data.email,
};
callback(null, user);
})
.catch((error) => {
callback(error, null);
});
};
// שימוש ב־fetchUserData עם פונקציית callback
fetchUserData(1, (error, user) => {
if (error) {
console.error(error);
} else {
console.log(user);
}
});
בדוגמה לעיל, יש לנו פונקציה בשם fetchUserData
שמקבלת id
ו־callback
כפרמטרים. פונקצית ה־callback
היא פונקציה עם שני פרמטרים: שגיאה ומשתמש.
הפונקציה fetchUserData
מאחזרת נתוני משתמש מנקודת קצה API של JSONPlaceholder באמצעות ה-id
. אם האחזור הוא מוצלח, היא יוצרת אובייקט User
ומעבירה אותו לפונקציית ה- callback עם שגיאה ריקה. אם יש שגיאה במהלך האחזור, היא שולחת את השגיאה לפונקציית ה- callback עם משתמש ריק.
כדי להשתמש בפונקציית fetchUserData
עם callback, אנו מספקים id
ופונקציית callback כארגומנטים. פונקציית ה- callback בודקת שגיאות ומציין את נתוני המשתמש אם אין שגיאות.
התמונה למטה מציגה את תוצאות שיחות ה- API:
איך להשתמש ב-callbacks באופן אחראי
בעוד callbacks הם יסודיים לתכנות אסינכרוני ב TypeScript, יש צורך בניהול זהיר כדי למנוע "גיהינום ה-callback" – הקוד המקוננן בצורת פירמידה, שעלול להיות קשה לקריאה ותחזוקה. הנה כיצד להשתמש ב-callbacks בצורה יעילה:
-
להימנע מהקניין העמוק
-
לשטח את מבנה הקוד על ידי פיצול פעולות מורכבות לפונקציות בשמות
-
השתמשו ב-promises או ב-async/await לזרימות עבודה אסינכרוניות מורכבות (יותר על כך למטה)
-
-
טיפול בשגיאות קודם
-
תמיד עקוב אחרי הקונבנציה של Node.js של
(שגיאה, תוצאה)
כפרמטרים -
בדוק שגיאות בכל רמה של קריאות חוזרות מעוגלות
-
function processData(input: string, callback: (err: Error | null, result?: string) => void) {
// ... תמיד התקשר לקריאה עם שגיאה קודם
}
-
השתמש בהערות סוג
-
נצל את מערכת הסוגים של TypeScript כדי לאכוף חתימות קריאה חוזרת
-
הגדר ממשקים ברורים עבור פרמטרים של קריאות חוזרות
-
type ApiCallback = (error: Error | null, data?: ApiResponse) => void;
-
שקול ספריות לניהול זרימה
עבור פעולות אסינכרוניות מורכבות, השתמש בכלים כמוasync.js
עבור:-
ביצוע מקבילי
-
ביצוע סדרתי
-
צינורות טיפול בשגיאות
-
מתי להשתמש ב-callbacks בניגוד לאלטרנטיבות
יש רגעים שבהם קולבקים הם בחירה טובה, ורגעים אחרים בהם הם לא.
קולבקים מועילים כאשר אתה עובד עם פעולות אסינכרוניות (השלמה יחידה), מתממשק עם ספריות ישנות או APIים שמצפים ל-callbacks, טופל באזני אירועים (כמו אזניות לחיצה או אירועי websocket) או יוצר כלים קלים עם צרכים אסינכרוניים פשוטים.
בתרחילת תרחיל, במקרים אחרים שבהם עליך להתמקד בכתיבת קוד נשמר עם זרימת אסינכרונית ברורה, קולבקים יכולים לגרום לבעיות ויש לתת עדיפות ל-promises או ל-async-await. לדוגמה, כאשר עליך לשרשר מספר פעולות, לטפל בהפצת שגיאות מורכבת, לעבוד עם APIים מודרניים (כמו Fetch API או FS Promises), או להשתמש ב-promise.all()
לביצוע פרללי.
דוגמה להעברה מ-callbacks אל promises:
// גרסת קול-באק
function fetchUser(id: number, callback: (err: Error | null, user?: User) => void) {
// ...
}
// גרסת פרומיס
async function fetchUserAsync(id: number): Promise<User> {
// ...
}
// שימוש עם async/await
try {
const user = await fetchUserAsync(1);
} catch (error) {
// טיפול בשגיאות
}
התפתחות התבניות האסינכרוניות
תבנית | יתרונות | חסרונות |
קול-באקים | פשוט, אוניברסלי | מורכבות מקוננות |
פרומיסים | ניתן לשרשר, זריזות טובה של שגיאות | דורש .then() שרשורים |
Async/Await | נקראות כמו סינכרוני | דורש שימוש בטרנספילציה |
פרויקטים מודרניים של TypeScript נהגים להשתמש בשילוב: קול-באקים לתבניות המבוססות על אירועים ופרומיסים/async-await ללוגיקת אסינכרונית מורכבת. המפתח הוא לבחור את הכלי הנכון למקרה השימוש המסוים שלך תוך שמירה על בהירות הקוד.
מסקנה
במאמר זה, למדנו על הדרכים השונות לטיפול בקוד אסינכרוני ב- TypeScript. למדנו על קול-באקים, פרומיסים, async/await, וכיצד להשתמש בהם ב- TypeScript. למדנו גם על המושג הזה.
אם ברצונך ללמוד עוד על תכנות וכיצד להפוך למהנדס תוכנה טוב יותר, תוכל להירשם לערוץ ה-YouTube שלי CliffTech.
תודה שהקדשת מזמנך לקרוא את המאמר שלי. אני מקווה שנהנית ממנו. אם יש לך שאלות, אל תהסס לפנות אליי.
התחבר אליי ברשתות החברתיות: