Promiseها
فنجان یک پاراگراف است، #cup. اول blank است و اسکریپت پیش از چای خواستن، waiting مینویسد.
pour نوشیدنی را پس نمیدهد. یک Promise پس میدهد. با then از همان Promise میخواهی نوشیدنی را دیرتر بنویسد. خط زیر pour هنوز waiting است. خط صفحه میشود waiting / lida tea.
این همان فنجانی نیست که همین الان سرو شد
صفحهٔ قبل done را به serve سپرد. serve پیش از برگشتن صدا زد، پس لاگ زیرش از قبل lida tea / poured بود. آنجا چیزی منتظر نماند.
اینجا تابعی که به then میدهی روی خط بعدی اجرا نمیشود. pour اول برمیگردد. نوشیدنی وقتی دیده میشود که این اسکریپت تمام شده باشد.
سه حالت
Promise تا وقتی مستقر نشده pending است. resolve آن را با یک مقدار fulfilled میکند. reject آن را با یک دلیل rejected میکند. then فقط برای fulfilled اجرا میشود. catch فقط برای rejected. این صفحه تایمر ندارد. تابع سازنده همان لحظه resolve یا reject را صدا میزند، و باز هم handlerها تا پایان اسکریپت صبر میکنند.
📊 سه حالت
| حالت | چه میبینی | قاطیکردن آسان |
|---|---|---|
| pending | فنجان هنوز waiting است | نوشیدنی از قبل روی فنجان است |
| fulfilled | then مقدار lida tea را میگیرد | catch هم اجرا شود |
| rejected | catch مقدار no leaves را میگیرد | then نوشیدنی را بگیرد |
سازنده الان است، handler نه
تابعی که به new Promise میدهی همان لحظه اجرا میشود. برای همین resolve("lida tea") میتواند پیش از برگشتن pour اتفاق بیفتد. تابعی که به then میدهی جور دیگری است. در صف میماند. خط بعد از pour(...) هنوز وقتی اجرا میشود که فنجان waiting است.
خط بعدی هنوز منتظر است
pour("lida") یک Promise را در order میگذارد. فنجان waiting شده بود. لاگ همان کلمه است، نه نوشیدنی.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
cup.textContent = "waiting";
let order = pour("lida");
console.log(cup.textContent);
لاگ waiting است. order خود Promise است. رشتهٔ lida tea نیست.
then نوشیدنی را میگیرد
then را با یک تابع صدا بزن. آن تابع مقداری را میگیرد که به resolve داده شد. نوشیدنی را مینویسد و لاگ میکند. این لاگ، لاگ خط بعدی نیست. لاگ داخل then است.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
pour("lida").then(function (drink) {
cup.textContent = drink;
console.log(cup.textContent);
});
لاگ lida tea است. رشتهٔ خالی به این handler نمیرسد.
برگ چای نیست
pour("") مقدار reject("no leaves") را صدا میزند و برمیگردد. catch آن دلیل را میگیرد. then اجرا نمیشود.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
pour("").catch(function (reason) {
console.log(reason);
});
لاگ no leaves است.
Promise خود نوشیدنی نیست
order.then یک تابع است. از همین میفهمی order یک Promise است، نه رشتهای که میخواستی. مقایسهٔ Promise با "lida tea" نادرست است، و این قطعه فقط نوع then را چاپ میکند.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let order = pour("lida");
console.log(typeof order.then);
لاگ function است.
خط زیر فنجان
اسکریپت فنجان را waiting میکند و همان لحظه این کلمه را ذخیره میکند. then مقدار lida tea را میگذارد و دو کلمه را به هم میچسباند. چسباندن داخل then است، پس بعد از اسکریپت است، نه روی خط بعدی.
<!DOCTYPE html>
<html>
<head>
<title>promised-cup — page</title>
</head>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
let seen = [];
cup.textContent = "waiting";
seen.push(cup.textContent);
pour("lida").then(function (drink) {
seen.push(drink);
cup.textContent = drink;
document.getElementById("line").textContent = seen.join(" / ");
});
</script>
</body>
</html>
خط waiting / lida tea است. waiting همان لحظه بود. lida tea داخل then آمد. کلمهٔ blank رفته. lida tea / poured مال صفحهٔ قبلی است.
پشت پیشخوان
- فنجان را waiting بگذار،
pour("lida")را صدا بزن، و همان لحظه فنجان را لاگ کن. لاگ waiting است. - نوشیدنی را داخل
thenروی فنجان بگذار. آن لاگ lida tea است. pour("")را صدا بزن و دلیل را باcatchبگیر. لاگ no leaves است.typeof order.thenرا بخوان. لاگ function است.- خط صفحه را بخوان: waiting / lida tea.
اشتباههای پشت پیشخوان
فنجان تا اجرای then میگوید waiting. poured نمیگوید.
- انتظار اینکه لاگ زیر
pourبرابر lida tea باشد - گرفتن مقدار برگشتی بهجای رشتهٔ نوشیدنی
- برای سفارش خالی
thenگذاشتن و جا انداختن no leaves - برای lida از
catchانتظار no leaves داشتن - خواندن خط بهصورت lida tea / poured
این را نگه دار
pourیک Promise برمیگرداند، نه رشتهٔ lida tea- خط بعدی هنوز waiting را لاگ میکند
thenبعد از این اسکریپت مقدار lida tea را میگیرد- سفارش خالی با no leaves رد میشود و
catchآن را لاگ میکند - خط صفحه waiting / lida tea است
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود