در حال بارگذاری...

تابع‌های callback

فنجان یک پاراگراف است، #cup، و اول blank است. تایمر کتری این‌جا نیست.
serve سفارش می‌گیرد و یک تابع. آن تابع callback است: تو می‌سپاری‌اش، serve صدا می‌زند. این صدا پیش از برگشتن serve اتفاق می‌افتد، پس خط بعدی از قبل نوشیدنی را دیده. خط می‌شود lida tea / poured.

این کتری نیست

صفحهٔ قبل همان لحظه cold را لاگ کرد و hot را ۴۰۰ میلی‌ثانیه بعد. خطش cold / hot / 3 بود. تایمر صبر می‌کند. serve صبر نمی‌کند. اگر setTimeout می‌خواهی، پیشخوان اشتباهی هستی.
سؤال این است که تابعِ سپرده‌شده را چه کسی صدا می‌زند.

اسم پارامتر فقط یک اسم است

داخل serve پارامتر done نام دارد. سرِ صدا زدن، خود تابع اسم ندارد. برای serve اسم مهم نیست. مهم این است که یک تابع گرفته و آن را با یک آرگومان صدا بزند: سفارش به‌علاوهٔ کلمهٔ tea.

صدا پیش از برگشتن است

done(order + " tea") اجرا می‌شود، فنجان پر می‌شود، و بعد serve تمام می‌شود. لاگی که زیر این فراخوانی است از قبل نوشیدنی است.

یک تابع را بسپار

javascript
function serve(order, done) {
done(order + " tea");
}
let cup = document.getElementById("cup");
serve("lida", function (drink) {
cup.textContent = drink;
});
console.log(cup.textContent);

لاگ lida tea است. فنجان blank نماند و چیزی هم صبر نکرد.

صدا را جا بینداز

این serve نوشیدنی را می‌سازد و می‌ایستد. done را صدا نمی‌زند. تابعی که سپردی همان‌جا می‌ماند. فنجان را پیش از فراخوانی blank کردیم و blank می‌ماند.

done را صدا نزن

javascript
function serve(order, done) {
order = order + " tea";
}
let cup = document.getElementById("cup");
cup.textContent = "blank";
serve("lida", function (drink) {
cup.textContent = drink;
});
console.log(cup.textContent);

لاگ blank است. خطایی پرتاب نمی‌شود. callbackی که صدا زده نشود اصلاً اجرا نمی‌شود. رشتهٔ نوشیدنی ساخته شد و کسی تحویلش نگرفت.

تابع دوم، بعد از اولی

serve می‌تواند دو تابع بگیرد. اول done را با نوشیدنی صدا می‌زند. after را فقط وقتی صدا می‌زند که آن صدا برگشته باشد. after نوشیدنی را نمی‌گیرد. فقط علامت می‌گذارد که ریختن انجام شد.

اول done، بعد after

javascript
function serve(order, done, after) {
done(order + " tea");
after();
}
let seen = [];
serve(
"lida",
function (drink) {
seen.push(drink);
},
function () {
seen.push("poured");
}
);
console.log(seen.join(" / "));

لاگ lida tea / poured است. اگر داخل serve جای دو صدا را عوض کنی، کلمه‌ها هم جا‌به‌جا می‌شوند. ترتیب، ترتیب صدا زدن است، نه ترتیبی که عبارت تابع را نوشتی.

صفحه چه را به هم می‌چسباند

صفحه همان serve دوم را به کار می‌برد، آن که done و after دارد. نوشیدنی را می‌گذارد، بعد poured را، و خط را می‌نویسد. بینشان تأخیر نیست.

خط زیر فنجان

اسکریپت ته body است. serve هر دو تابع را پیش از چسباندن خط صدا می‌زند.

نمایش صفحه — فنجان

html
<!DOCTYPE html>
<html>
<head>
<title>serve-cup — page</title>
</head>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
function serve(order, done, after) {
done(order + " tea");
after();
}
let seen = [];
serve(
"lida",
function (drink) {
seen.push(drink);
},
function () {
seen.push("poured");
}
);
document.getElementById("line").textContent = seen.join(" / ");
document.getElementById("cup").textContent = seen[0];
</script>
</body>
</html>

خط lida tea / poured است. فنجان lida tea را نشان می‌دهد. کلمهٔ blank رفته. cold / hot / 3 مال صفحهٔ قبلی است.

پشت پیشخوان

  1. تابعی را به serve بسپار و بگذار خودش با نوشیدنی صدا بزند. لاگ lida tea است.
  2. serveای را به کار ببر که done را صدا نمی‌زند. لاگ blank می‌ماند.
  3. done و after را بسپار. لاگ lida tea / poured است.
  4. خط صفحه را بخوان: lida tea / poured.

اشتباه‌های پشت پیشخوان

فنجان یا نوشیدنی را نشان می‌دهد یا blank می‌ماند. شمارش interval را نشان نمی‌دهد.

  • انتظار اینکه لاگ زیر serve هنوز blank باشد، در حالی که done صدا زده شده
  • گمان اینکه callback حتی اگر serve صدا نزند اجرا می‌شود
  • ۴۰۰ میلی‌ثانیه منتظر lida tea ماندن
  • با صدا زدن after در اول، poured را قبل از نوشیدنی گذاشتن
  • خواندن خط به‌صورت cold / hot / 3

این را نگه دار

  • callback تابعی است که می‌سپاری تا دیگری صدا بزند
  • serve پیش از برگشتن done را صدا می‌زند، پس خط بعدی از قبل lida tea را دیده
  • اگر done صدا زده نشود، فنجان blank می‌ماند و خطایی هم نیست
  • after فقط بعد از برگشتن done اجرا می‌شود
  • خط صفحه lida tea / poured است

🧠 دانش خود را بیازمایید

آماده شروع

دانش خود را بیازمایید

خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کرده‌اید

❓
6
سوالات
🎯
70%
برای قبولی
♾️
∞
زمان
🔄
∞
تلاش‌ها

📝 دستورالعمل‌ها

  • هر سوال را با دقت بخوانید
  • بهترین پاسخ را برای هر سوال انتخاب کنید
  • می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید
  • پیشرفت شما در بالا نمایش داده می‌شود