backend developer | telegram : @ali256reza
پرامیس ها در جاوااسکریپت | Promises in JavaScript
برای این که پرامیس ها رو بفهمیم باید اول این موضوعات رو بررسی کنیم :
Blocking vs Non-Blocking
عملگر هایی که یک ترد thread اپلیکیشن جاوا اسکریپت رو مشغول می کنند ( به اصطلاح بلاک می کنند ) ، عملگر های blocking هستند.
حالا مشکل این عملگر ها کجاست؟
- جاوااسکریپت فقط یک ترد داره و وقتی اون ترد درگیر بشه باید صبر کنه تا اون ترد آزاد بشه بعد به بقیه در خواست ها پاسخ بده!
ولی ما این مشکل رو با عملگر های non-blocking نداریم چون این عملگر ها ترد رو به طور کامل مشغول نمی کنند.
عملگر های blocking به صورت synchronous کار می کنند و عملگر های non-blocking به صورت asynchronous کار می کنند.
به طور ساده تر بخوام بگم ، یک رستوران گارسون های زیادی داره و برای ثبت سفارش مشتری ها گارسون کم نمیاره پس هر گارسون به سراغ یک میز میره و منو غذا ها رو تحویل میده و منتظر می مونه تا مشتری سفارش رو بده (مثال برای synchronous) ، تا وقتی که تعداد گارسون ها زیاد باشه مشکلی پیش نمیاد ولی اگر گارسون ها کم باشن راه حل اینه :
گارسون سراغ یک میز میره و منو رو تحویل میده و سراغ میز بعدی میره ، وقتی مشتری سفارشش رو انتخاب کرد گارسون رو خبر می کنه تا سفارش رو ثبت کنه (مثال برای asynchronous)
Talk is cheap show me the code!
یک مثال از متد های synchronous :
const fs = require('fs');
const data = fs.readFileSync('/file.txt');
وقتی متد readFileSync اجرا میشه process (روند) اپلیکیشن جاوا اسکریپت متوقف میشه تا فایل file.txt رو بخونه.
یک مثال از متد های asynchronous :
const fs = require('fs');
function callback(err, data) {
if (err) throw err;
}
fs.readFile('/file.md', callback);
ولی وقتی متد readFile اجرا میشه روند اپلیکیشن متوقف نمیشه و ادامه پیدا می کنه و زمانی که اطلاعات مورد نظر بدست اومد ، تابع callback صدا زده میشه و اطلاعات مورد نظر رو میشه از پارامتر data بدست آورد.
نکته : تا جای ممکن از متد های asynchronous استفاده کنید تا پراسس مشغول نشه!!
بجز callback ها روش های دیگه ای هم برای گرفتن مقدار از متد های asynchronous هست ....
حالا بر می گردیم به بحث پرامیس ها :
پرامیس معنی لغویش "قول دادن" هست ، در عمل یعنی پرامیس ها به شما قول میدن که یک جواب در ازای متدی که صدا زدید میده (چه اون جواب یک ارور باشه یا یک مقدار).
دو راه برای گرفتن مقدار پرامیس ها :
- then, catch
- async, await
then, catch
نکته : کلاس Promise یک کلاس گلوبال جاوااسکرپیته برای ساختن پرامیس ها
یک مثال برای این نوع :
var p1 = new Promise((resolve, reject) => {
resolve('Success!');
// or //
reject(new Error("Error!"))
});
p1.then(value => { console.log(value); // Success! })
.catch(reason => { console.error(reason); // Error! });
اگر عملیات موفق بود .then اجرا میشه ولی اگر موفق نبود .catch
async, await
یک مثال برای این نوع :
var p1 = new Promise((resolve, reject) => {
resolve('Success!');
// or //
reject(new Error("Error!"))
});
async function getValue() {
const value = await p1;
console.log(value);
}
getValue();
وقتی تابع getValue صدا زده میشه پرامیس مقداری که باید رو میده (برای catch کردن ارور ها باید از try, catch استفاده کنید)
توی این مقاله به صورت خیلی سطحی به این مبحث پرداختیم در مقاله های بعدی به صورت کامل تر توضیح میدم :)
مطلبی دیگر از این انتشارات
مشکل نصب eslint
مطلبی دیگر از این انتشارات
بررسی event propagation در جاوااسکریپت
مطلبی دیگر از این انتشارات
چگونه توابع (functions) در جاوا اسکریپت کار می کنند؟؟