راهنمای مبتدی برای همگام سازیانتظار جاوا اسکریپت، همراه با مثال

راهنمای مبتدی برای همگام سازیانتظار جاوا اسکریپت، همراه با مثال

راهنمای مبتدی برای همگام سازی/انتظار جاوا اسکریپت، همراه با مثال

کلمات کلیدی async و await در جاوا اسکریپت یک نحو مدرن ارائه می‌کنند تا به ما در مدیریت عملیات ناهمزمان کمک کنند. در این آموزش، نگاهی عمیق به نحوه استفاده از async/await برای تسلط بر کنترل جریان در برنامه‌های جاوا اسکریپت خواهیم داشت. ایجاد تیم های طراحی وب سایت موثر

محتوا:

  1. نحوه ایجاد یک تابع Async جاوا اسکریپت
  2. جاوا اسکریپت در انتظار/Async از وعده‌های زیر سرپوش استفاده می‌کند
  3. بررسی خطا در توابع Async
  4. اجرای دستورات ناهمزمان به صورت موازی
  5. ناهمزمان در حلقه‌های همزمان در انتظار است
  6. انتظار سطح بالا
  7. نوشتن کد ناهمزمان با اطمینان

در جاوا اسکریپت، برخی از عملیات ناهمزمان هستند. این بدان معناست که نتیجه یا ارزشی که تولید می‌کنند فوراً در دسترس نیست.

کد زیر را در نظر بگیرید:

عملکرد fetchDataFromApi() {
  
  کنسول.ورود(داده);
}

fetchDataFromApi();
کنسول.ورود('واکشی داده به پایان رسید');

مفسر جاوا اسکریپت منتظر نمی ماند تا عملکرد ناهمزمان fetchDataFromApi قبل از رفتن به عبارت بعدی تکمیل شود. در نتیجه، قبل از ثبت اطلاعات واقعی بازگردانده شده از API، Finished Fetching Data را ثبت می کند.

در بسیاری از موارد، این رفتار مطلوب نیست. خوشبختانه، می‌توانیم از کلیدواژه‌های async و wait استفاده کنیم تا برنامه‌مان را قبل از ادامه کار منتظر کنیم تا عملیات ناهمزمان کامل شود.

این قابلیت در ES2017 به جاوا اسکریپت معرفی شد و در همه مرورگرهای مدرن.

نحوه ایجاد یک تابع Async جاوا اسکریپت

بیایید نگاهی دقیق‌تر به منطق واکشی داده‌ها در تابع fetchDataFromApi بیندازیم. واکشی داده ها در جاوا اسکریپت نمونه بارز عملیات ناهمزمان است.

با استفاده از واکشی API، می‌توانیم کاری شبیه به این انجام دهیم:

عملکرد fetchDataFromApi() {
  واکشی('https://v2.jokeapi.dev/joke/ برنامه نویسی?type=single')
    .سپس(res => res.json())
    .سپس(json => کنسول.ورود(json. شوخی));
}

fetchDataFromApi();
کنسول.ورود('واکشی داده به پایان رسید');

در اینجا، ما یک جوک برنامه‌نویسی را از JokeAPI دریافت می‌کنیم. پاسخ API در قالب JSON است، بنابراین پس از تکمیل درخواست، آن پاسخ را استخراج می کنیم (با استفاده از روش json())، سپس جوک را به کنسول وارد می کنیم.

لطفاً توجه داشته باشید که JokeAPI یک API شخص ثالث است، بنابراین نمی‌توانیم کیفیت جوک‌هایی را که بازگردانده می‌شوند تضمین کنیم!

اگر این کد را در مرورگر شما یا در Node (نسخه 17.5 و بالاتر با استفاده از پرچم --experimental-fetch) اجرا کنیم، خواهیم دید که چیزها همچنان در کنسول وارد می شوند. دستور اشتباه

بیایید آن را تغییر دهیم.

کلید کلیدی ناهمگام

اولین کاری که باید انجام دهیم این است که تابع حاوی را به عنوان ناهمزمان برچسب گذاری کنیم. ما می توانیم این کار را با استفاده از کلمه کلیدی async که در مقابل کلمه کلیدی function قرار می دهیم انجام دهیم:

ناهمگام عملکرد fetchDataFromApi()  {
  واکشی('https://v2.jokeapi.dev/joke/ برنامه نویسی?type=single')
    .سپس(res => res.json())
    .سپس(json => کنسول.ورود(json. شوخی));
}

توابع ناهمزمان همیشه یک وعده را برمی‌گردانند (در ادامه در مورد آن توضیح خواهیم داد)، بنابراین می‌توان با زنجیر کردن یک then() در فراخوانی تابع، ترتیب اجرای صحیح را دریافت کرد:

fetchDataFromApi()
  .سپس(() => { 
    کنسول.ورود('واکشی داده به پایان رسید');
  });

اگر کد را اکنون اجرا کنیم، چیزی شبیه به این می‌بینیم:

اگر بیل گیتس برای هر بار خرابی ویندوز یک سکه داشت... اوه صبر کنید، او این کار را می کند.
واکشی داده ها به پایان رسید

اما ما نمی خواهیم این کار را انجام دهیم! نحو وعده جاوا اسکریپت می تواند کمی پرمویی شود، و اینجاست که async/await می درخشد: به ما امکان می دهد کد ناهمزمان را با نحوی بنویسیم که بیشتر شبیه کد همزمان است و خواناتر است.

کلید واژه انتظار

کار بعدی این است که کلمه کلیدی wait را در مقابل هر عملیات ناهمزمان در تابع خود قرار دهیم. این کار مفسر جاوا اسکریپت را مجبور می‌کند تا اجرا را «مکث» کند و منتظر نتیجه بماند. ما می توانیم نتایج این عملیات را به متغیرها اختصاص دهیم:

ناهمگام عملکرد fetchDataFromApi()  {
  const res = انتظار واکشی('https://v2.jokeapi.dev/joke/Programming?type= single');
  const json = انتظار پاسخ .json();
  کنسول.ورود(json.جوک);
}

ما همچنین باید منتظر نتیجه فراخوانی تابع fetchDataFromApi باشیم:

انتظار fetchDataFromApi();
کنسول.ورود('واکشی داده به پایان رسید');

متأسفانه، اگر اکنون بخواهیم کد را اجرا کنیم، با خطا مواجه می‌شویم:

Error Syntax Uncaught: await فقط در توابع ناهمگام، ژنراتورهای ناهمگام و ماژول‌ها معتبر است

این به این دلیل است که ما نمی‌توانیم از wait خارج از تابع async در یک اسکریپت غیر ماژول استفاده کنیم. ما بعداً با جزئیات بیشتری به این موضوع خواهیم پرداخت، اما در حال حاضر ساده‌ترین راه برای حل مشکل این است که کد فراخوانی را در تابعی از خود بپیچانیم، که ما همچنین به عنوان ناهمگام علامت گذاری می شود:

ناهمگام عملکرد fetchDataFromApi()  {
  const res = انتظار واکشی('https://v2.jokeapi.dev/joke/Programming?type= single');
  const json = انتظار پاسخ .json();
  کنسول.ورود(json.جوک);
}

ناهمگام عملکرد init() {
  انتظار fetchDataFromApi();
  کنسول.ورود('واکشی داده به پایان رسید');
}

شروع();

اگر اکنون کد را اجرا کنیم، همه چیز باید به ترتیب صحیح خروجی شود:

UDP در دوران کووید بهتر است زیرا از دست دادن های غیرضروری جلوگیری می کند.
واکشی داده ها به پایان رسید

این واقعیت که ما به این دیگ بخار اضافی نیاز داریم مایه تاسف است، اما به نظر من خواندن کد همچنان آسان تر از نسخه مبتنی بر وعده است.

روش های مختلف اعلام توابع ناهمگام

مثال قبلی از دو اعلان تابع نامگذاری شده استفاده می کند (کلید کلیدی function به دنبال نام تابع)، اما ما به اینها محدود نمی شویم. همچنین می‌توانیم عبارات تابع، توابع پیکان و توابع ناشناس را به‌عنوان async علامت‌گذاری کنیم.

اگر می‌خواهید درباره تفاوت بین اعلان‌های تابع و عبارات توابع تجدید نظر کنید، راهنمای زمان استفاده از کدام.

بیان تابع همگام

یک عبارات تابع زمانی است که یک تابع ایجاد می کنیم و آن را به یک متغیر اختصاص می دهیم. تابع ناشناس است، به این معنی که نامی ندارد. به عنوان مثال:

const fetchDataFromApi = ناهمگام عملکرد() {
  const res = انتظار واکشی('https://v2.jokeapi.dev/joke/Programming?type= single');
  const json = انتظار پاسخ .json();
  کنسول.ورود(json.جوک);
}

این دقیقاً به همان شیوه کد قبلی ما کار می کند.

این مطلب را هم از دست ندهید :   ویژگی های اینستاگرام فارسی

عملکرد پیکان ناهمگام

توابع پیکان در ES6 به این زبان معرفی شدند. آنها یک جایگزین فشرده برای عبارات تابع هستند و همیشه ناشناس هستند. نحو اصلی آنها به شرح زیر است:

(پارام‌ها) => { تابع بدنه> }

برای علامت‌گذاری یک تابع پیکان به‌عنوان ناهمزمان، کلمه کلیدی async را قبل از پرانتز باز وارد کنید.

به عنوان مثال، یک جایگزین برای ایجاد یک تابع init اضافی در کد بالا، قرار دادن کد موجود در یک IIFE، که آن را به عنوان async علامت گذاری می کنیم:

(ناهمگام () => {
  ناهمگام عملکرد fetchDataFromApi() {
    const res = انتظار واکشی('https://v2.jokeapi.dev/joke/Programming?type= single');
    const json = انتظار پاسخ .json();
    کنسول.ورود(json.جوک);
  }
  انتظار fetchDataFromApi();
  کنسول.ورود('واکشی داده به پایان رسید');
})();

تفاوت زیادی بین استفاده از عبارات تابع یا اعلان تابع وجود ندارد: عمدتاً این فقط یک اولویت است. اما چند چیز وجود دارد که باید از آنها آگاه بود، مانند بالا بردن یا این واقعیت که یک تابع فلش خود را به مقدار این خود متصل نمی کند. برای جزئیات بیشتر می توانید پیوندهای بالا را بررسی کنید.

جاوا اسکریپت در انتظار/Async از وعده های زیر سرپوش استفاده می کند

همانطور که ممکن است قبلاً حدس زده باشید، async/wait تا حد زیادی، قند نحوی برای وعده‌ها است. بیایید با جزئیات بیشتری به این موضوع نگاه کنیم، زیرا درک بهتر از آنچه در زیر کاپوت اتفاق می‌افتد، به درک نحوه عملکرد async/await کمک زیادی می‌کند.

اگر مطمئن نیستید وعده‌ها چیست، یا اگر می‌خواهید یک تجدید نظر سریع داشته باشید، راهنمای وعده‌ها.

اولین چیزی که باید از آن آگاه بود این است که یک تابع async همیشه یک وعده را برمی‌گرداند، حتی اگر به صراحت به آن نگوییم که این کار را انجام دهد. به عنوان مثال:

ناهمگام عملکرد echo(arg ) {
  بازگشت arg;
}

const res = echo(5);
کنسول.ورود(res);

این موارد زیر را ثبت می‌کند:

وعده { : "اجرا شد"، : 5 }

یک قول می‌تواند در یکی از سه حالت باشد: در حال انتظار، اجرا شده، یا رد شده. یک وعده زندگی را در حالت معلق شروع می کند. اگر عمل مربوط به عهد با موفقیت انجام شود، قول وفاشده است. اگر عمل ناموفق باشد قولردمی شود. هنگامی که یک وعده محقق شد یا رد شد، اما در حال تعلیق نباشد، همچنین تسویه شده در نظر گرفته می شود.

وقتی از کلمه کلیدی wait در داخل یک تابع async برای “مکث” اجرای تابع استفاده می‌کنیم، آنچه واقعاً اتفاق می‌افتد این است که منتظر یک قول (یا صریح) هستیم. یا ضمنی) برای قرار گرفتن در وضعیت حل شده یا رد شده.

با تکیه بر مثال بالا، می‌توانیم کارهای زیر را انجام دهیم:

ناهمگام عملکرد echo(arg ) {
  بازگشت arg;
}

ناهمگام عملکرد getValue() {
  const res = انتظار echo(5);
  کنسول.ورود(res);
}

getValue();

زیرا تابع echo یک وعده را برمی‌گرداند و کلمه کلیدی wait در داخل تابع getValue منتظر می‌ماند تا این وعده قبل از ادامه برنامه اجرا شود. ، می توانیم مقدار مورد نظر را در کنسول ثبت کنیم.

Promises یک پیشرفت بزرگ برای کنترل جریان در جاوا اسکریپت است و توسط چندین API مرورگر جدیدتر استفاده می شود – مانند API وضعیت باتری، Clipboard API، واکشی API، API MediaDevices و غیره.

Node همچنین یک عملکرد promisify را به ماژول util داخلی خود اضافه کرده است. که کدی را تبدیل می کند که از توابع برگشت به تماس برای برگرداندن وعده ها استفاده می کند. و از نسخه 10، توابع موجود در ماژول fs Node می‌توانند مستقیماً وعده‌ها را برگردانند.

تغییر از وعده به async/wait

پس چرا هر یک از اینها برای ما مهم است؟

خب، خبر خوب این است که هر تابعی که یک وعده را برمی گرداند می تواند با async/await استفاده شود. من نمی گویم که ما باید همه چیزها را async/wait داشته باشیم (این نحو جنبه های منفی خود را دارد، همانطور که در هنگام رسیدگی به خطا خواهیم دید)، اما باید توجه داشته باشیم که این امکان پذیر است.

ما قبلاً نحوه تغییر تماس واکشی مبتنی بر قول خود را در بالای مقاله برای کار با async/await دیده‌ایم، بنابراین اجازه دهید به مثال دیگری نگاهی بیندازیم. در اینجا یک تابع کاربردی کوچک برای دریافت محتویات یک فایل با استفاده از API مبتنی بر وعده Node و روش readFile آن وجود دارد.

استفاده از Promise.then():

const { وعده می دهد : fs } = نیازمند('fs');

const getFileContents = عملکرد(fileName) {
  بازگشت fs.readFile (fileName، enc)
}

getFileContents('myFile.md'، 'utf-8')
  .سپس((مطالب) =>  {
    کنسول.ورود(contents);
  });

With async/await that becomes:

import { readFile } from 'node:fs/promises';

const getFileContents = function(fileName, enc) {
  return readFile(fileName, enc)
}

const contents = await getFileContents('myFile.md', 'utf-8');
console.log(contents);

Note: this is making use of a feature called top-level await, which is only available within ES modules. To run this code, save the file as index.mjs and use a version of Node >= 14.8.

Although these are simple examples, I find the async/await syntax easier to follow. This becomes especially true when dealing with multiple then() statements and with error handling thrown in to the mix. I wouldn’t go as far as converting existing promise-based code to use async/await, but if that’s something you’re interested in, VS Code can do it for you.

https://aliarm.ir/ایجاد-تیم-های-طراحی-وب-سایت-موثر/