جاوا اسکریپت ناهمزمان: وعده Async در انتظار!

جاوا اسکریپت ناهمزمان
قبل از اینکه کد جاوا اسکریپت ناهمزمان را بفهمیم، ابتدا باید بفهمیم که کد جاوا اسکریپت همزمان چیست (در اصل مقابل کد ناهمزمان)
کد سنکرون به سادگی به معنای کدی است که خط به خط به ترتیب دقیق اجرا اجرا می شود.
مثلا
const p = document.querySelector('.p');
p.textContent="My name is Cybermaxi";
alert('Text set');
p.style.color="red";
کد بالا خط به خط اجرا می شود، اگر خطایی مشکلی داشت، بقیه خطوط کد اجرا نمی شوند.
به عنوان مثال روش هشدار که یک پنجره پاپ آپ را بیرون می آورد، اگر روی ok کلیک نکنیم، بقیه خطوط کد اجرا نمی شوند. این است مسئله با کد سنکرون
با این حال، کد ناهمزمان پس از اتمام کاری که در پسزمینه اجرا میشود، اجرا میشود. اجرا قبل از اجرا منتظر نمی ماند تا کد ناهمزمان تمام شود
مثلا
const p = document.querySelector('.p');
setTimeout(function(){
p.textContent="My name is Cybermaxi";
}, 5000);
p.style.color="red";
تابع setTimeout ناهمزمان است به این دلیل که تابع تماس آن پس از اتمام زمان پایان اجرا خواهد شد. دیگر خطوط کد را مسدود نمی کند یا مانع از اجرای آن نمی شود، به سادگی در پس زمینه اجرا می شود. هر زمان که تایمر تمام شود (5 ثانیه)، عملکرد برگشت به تماس اجرا می شود.
بنابراین می توان گفت برنامه نویسی ناهمزمان رفتار هماهنگ کننده یک برنامه در یک دوره زمانی معین است
NB توابع Callback به تنهایی یک کد را ناهمزمان نمی کنند، برای مثال map() که حاوی یک callback است ناهمزمان نیست.
نمونه ای از رفتار ناهمزمان در جاوا اسکریپت عبارتند از Geolocation API، تماس های AJAX و غیره
این ما را به AJAX می رساند.
تماس های AJAX چیست؟
جاوا اسکریپت ناهمزمان و XML (AJAX) به ما این امکان را می دهد که با سرورهای وب به صورت ناهمزمان ارتباط برقرار کنیم. با AJAX می توانیم داده ها را از وب سرورها به صورت پویا درخواست کنیم.
چگونه کار می کند
فرض کنید برنامه وب ما در مرورگر (مشتری) ما در حال اجرا است، میتوانیم دادههای خاصی را که نیاز داریم از یک وب سرور درخواست کنیم (از سرور وب درخواست کنیم)، سپس وب سرور پاسخی را برای ما ارسال میکند که ممکن است حاوی دادههای ما باشد. هنگام تلاش برای دریافت آن داده، نیاز یا خطایی رخ داده است.
توجه داشته باشید که هنگام درخواست، میتوانیم GET (واکشی دادهها) یا POST (ارسال داده) به سرورهای وب را ارسال کنیم. سرورهای وب معمولا حاوی یک وب API هستند
وب API چیست؟
API مخفف Application Programming Interface است. این یک نرم افزار است که می تواند توسط نرم افزار دیگری استفاده شود تا برنامه ها با یکدیگر صحبت کنند.
همچنین می توان آن را به عنوان یک برنامه در حال اجرا بر روی یک سرور مشاهده کرد دریافت می کند درخواست داده و ارسال داده ها به عنوان واکنش.
NB یک API برای همه چیز وجود دارد!
در جاوا اسکریپت راه های مختلفی برای برقراری تماس های AJAX وجود دارد، اما اجازه دهید با قدیمی ترین آنها شروع کنیم که از XMLHttpRequest();
این XMLHttpRequest() شی برای تعامل با سرورها استفاده می شود، شما می توانید داده ها را از یک URL بدون نیاز به بارگذاری مجدد کامل صفحه بازیابی کنید، این یک صفحه وب را قادر می سازد تا بخشی از صفحه را بدون ایجاد اختلال در کاری که کاربر انجام می دهد به روز کند.
با وجود نام آن، می توان از آن برای بازیابی هر نوع داده و نه فقط XML استفاده کرد
به عنوان مثالconst request = new XMLHttpRequest()
-
خط کد بالا یک شی XMLHttpRequest جدید ایجاد می کند
-
مرحله بعدی فراخوانی متد open() روی شی درخواست با پارامترهای زیر است
request.open('GET', 'https://url of the api')
3.
مرحله بعدی فراخوانی متد send() استrequest.send();
در این مرحله، اینجا جایی است که جاوا اسکریپت ناهمزمان اتفاق می افتد. درخواست ارسال می شود و ما منتظر پاسخ از API هستیم، همه اینها در پشت صحنه اتفاق می افتد، بنابراین مانعی برای اجرای هیچ خط کدی که ممکن است بعد از آن بیاید، نمی شود. -
مرحله بعدی این است که یک شنونده رویداد را روی شی درخواست ضمیمه کنید تا به رویداد بارگذاری گوش دهد و سپس کاری را با پاسخ انجام دهید
request.addEventListener('load', function(){
console.log(this.responseText)
})
تعجب می کنید که answerText از کجا آمده است؟ این یک نام متغیر است که به طور خودکار توسط XMLHttpRequest ایجاد می شود و حاوی داده هایی است که ما درخواست کرده ایم.
توجه داشته باشید که دادههایی که دریافت میکنید در قالب رشتهای خواهند بود، بنابراین باید آنها را به یک شی تبدیل کنیمconst data = JSON.parse(this.responseText);
راه دوم و اصلی درخواست به API است رفتن و آوردن()
ما به سادگی انجام می دهیم
const request = fetch(url);
متد fetch a را برمی گرداند وعده که ما را به وعده ها می رساند
وعده ها چیست؟
-
یک Promise را می توان به عنوان یک شی در نظر گرفت که به عنوان یک مکان نگهدار برای نتیجه آینده یک عملیات ناهمزمان استفاده می شود.
-
یک Promise همچنین می تواند به عنوان محفظه ای برای یک مقدار تحویل ناهمزمان دیده شود
-
به زبان ساده، یک وعده ظرفی برای ارزش آتی است.
نمونه ای از چنین مقداری پاسخ از تماس های AJAX است
دو (2) مزیت استفاده از وعده ها
- دیگر لازم نیست برای رسیدگی به نتایج ناهمزمان به رویدادها و تماس های ارسال شده به توابع ناهمزمان تکیه کنیم.
- بهجای تودرتو کردن تماسهای برگشتی، میتوانیم وعدههای زنجیرهای را برای توالی عملیات ناهمزمان زنجیرهای کنیم و بدین ترتیب از جهنم پاسخ به تماس فرار کنیم.
از آنجایی که وعدهها با عملیات ناهمزمان کار میکنند، به زمان حساس هستند و در نتیجه میتوانند در حالتهای مختلف باشند، به این حالت میگویند. چرخه زندگی وعده
هنگامی که یک وعده آغاز می شود، آن را در انتظار حالت، سپس وظیفه ناهمزمان حل می شود و در این حالت حل شده دو حالت وجود دارد: برآورده شده و مردود حالت
- وضعیت تحقق یافته به معنای موفقیت است، ارزش یا پاسخ اکنون در دسترس است
- قول رد شده به این معنی است که یک اشتباه رخ داده است، بنابراین یک وعده شکست خورده است.
fetch('url').then(response => response.json())
.then(data => console.log(data))
Fetch API یک وعده را برمیگرداند که در صورت تحقق، پاسخی را ارائه میدهد، اکنون این پاسخ تنها با فراخوانی متد json() روی آن قابل دسترسی است. پس از فراخوانی، پاسخ دیگری را برمیگرداند که در نتیجه دادههایی را که درخواست کردهایم در اختیار ما قرار میدهد.
ساختن یک وعده
ما از وعدهها استفاده کردهایم، اما حالا اجازه دهید قول جدید خود را ایجاد کنیم. یک وعده به سادگی یک شی جاوا اسکریپت است و سازنده ای است که تنها یک آرگومان را می پذیرد که تابع مجری نامیده می شود.. این تابع دارای دو آرگومان است که پارامترهای Resol و Reject است
const newPromise = new Promise(function(resolve, reject){})
مورد استفاده
const lotteryPromise = new Promise(function(resolve, reject){
console.log('Lottery has began')
setTimeout(function(){
if (Math.random() >= 0.5) {
resolve('You Win');
} else {
reject new Error('You Lost')
}
}, 2000)
})
حالا بیایید وعده را مصرف کنیمlotteryPromise.then(res => console.log(res)).catch(err => console.error(err))
با این حال ما می توانیم وعده ها را به روشی کارآمدتر با استفاده از آن مصرف کنیم ASYNC در انتظار غیر از روش آن زمان زنجیره ای
در Async Await، هنگام تعریف تابع، کلمه کلیدی async را اعلام میکنیم تا آن تابع را به یک تابع ناهمگام تبدیل کنیم و سپس کلمه کلیدی await را به هر عملیات ناهمزمانی مانند fetch() اضافه میکنیم که یک وعده تولید میکند. این در انتظار به سادگی به این معنی است که منتظر تحقق وعده باشید و یکی از زیباییهای این کار این است که میتوانیم پاسخ را در متغیری ذخیره کنیم که قبلاً نمیتوانستیم انجام دهیم
const getNumbers = async function() {
const res = await fetch(url);
const data = await res.json();
}
آیا این در مقایسه با وعده و سپس روش زنجیره ای ساده نیست؟
اما چه اتفاقی میافتد وقتی میخواهیم چندین وعده را به طور همزمان انجام دهیم یا به یکدیگر وابسته نباشیم، میتوانیم
const getThreeNumbers = async function() {
const data1 = await firstPromise();
const data2 = await secondPromise();
const data3 = await thirdPromise();
const [result] = [data1, data2, data3];
}
با این حال مشکل کد بالا این است که هر وعده قبل از اجرا باید منتظر باشد تا وعده قبلی محقق شود، اما اگر بخواهیم همه آنها را همزمان اجرا کنیم، می توانیم از چیزی استفاده کنیم که به آن گفته می شود. Promise.all() و این یک وعده واحد را برمی گرداندconst result = Promise.all([
await firstPromise();
await secondPromise();
await thirdPromise();
])
با وجود طولانی بودن پست، امیدوارم چیز مفیدی پیدا کرده باشید و یکی دو چیز یاد گرفته باشید.
در مورد چیزی که یاد گرفتید و بهبودها یا موارد اضافه شده به پست من نظر بدهید
ممنون 😊