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

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 شده بود. لاگ همان کلمه است، نه نوشیدنی.

فنجان هنوز منتظر است

javascript
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 است.

then نوشیدنی را می‌نویسد

javascript
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 اجرا نمی‌شود.

سفارش خالی را بگیر

javascript
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 را چاپ می‌کند.

then یک تابع است

javascript
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 است، پس بعد از اسکریپت است، نه روی خط بعدی.

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

html
<!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 مال صفحهٔ قبلی است.

پشت پیشخوان

  1. فنجان را waiting بگذار، pour("lida") را صدا بزن، و همان لحظه فنجان را لاگ کن. لاگ waiting است.
  2. نوشیدنی را داخل then روی فنجان بگذار. آن لاگ lida tea است.
  3. pour("") را صدا بزن و دلیل را با catch بگیر. لاگ no leaves است.
  4. typeof order.then را بخوان. لاگ function است.
  5. خط صفحه را بخوان: 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 است

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

آماده شروع

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

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

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

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

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