۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

ویژگی های ECMAScript 2024 که اکنون می توانید از آنها استفاده کنید

انتظار می‌رود ECMAScript 2024 در ماه ژوئن نهایی شود، اما چهار ویژگی جدید جاوا اسکریپت در حال حاضر در مرورگرها و Node.js پشتیبانی می‌شوند. در اینجا نحوه شروع استفاده از آنها از امروز آمده است.

انتظار می‌رود ECMAScript 2024 در ماه ژوئن نهایی شود، اما چهار ویژگی جدید جاوا اسکریپت در حال حاضر در مرورگرها و Node.js پشتیبانی می‌شوند. در اینجا نحوه شروع استفاده از آنها از امروز آمده است.

مشخصات ECMAScript مانند پرتره ای از زبان جاوا اسکریپت است که هر سال دوباره رنگ می شود. همانطور که در جاوا اسکریپت مدرن معمول است، مشخصات و تمرین در دنیای واقعی پشت سر هم حرکت می کنند. جدیدترین نسخه مشخصات، ECMAScript 2024، شامل هفت ویژگی جدید جاوا اسکریپت است و انتظار می‌رود در ژوئن نهایی می شود. این مقاله چهار مورد از ویژگی‌های جدیدی را معرفی می‌کند که در حال حاضر در مرورگرها و محیط‌های سمت سرور در دسترس هستند و برای استفاده امروز آماده هستند:

  • Promise.withResolvers یک مکانیسم قدرتمند برای مدیریت عملیات ناهمزمان در زمانی است که کنترل خارجی بر روی وضوح و رد کردن ضروری است.
  • Object.groupBy و Map.groupBy به شما امکان می‌دهند مجموعه‌ها را بر اساس ویژگی‌های کلیدی سازماندهی کنید.
  • Atomics.waitAsync ارتباط امن و همگام‌سازی بین رشته‌های کارگر را تسهیل می‌کند.
  • String.isWellFormed و String.toWellFormed ابزارهای ارزشمندی برای مدیریت داده‌های ورودی و شبکه کاربر اضافه می‌کنند.

Promise.withResolvers

اجازه دهید با روش استاتیک جدید در Promise به نام withResolvers() شروع کنیم. وعده های جاوا اسکریپت راه های مختلفی را برای مقابله با عملیات ناهمزمان به ما می دهد. روش withResolvers() برای ایجاد سه بخش یک Promise استفاده می‌شود: خود Promise و resolve() و reject().

مزایای withResolvers() این است که هر سه را به عنوان مرجع در معرض دید خارجی ایجاد می کند. در مواردی که می خواهید یک وعده ایجاد کنید و همچنین به حل و رد قول از کد خارجی دسترسی داشته باشید، این روشی است که باید استفاده کنید.

خود مشخصات مشخصاً در توضیحات آن اسپارت است. مستندات موزیلا جزئیات بیشتری را ارائه می‌کند نکته کلیدی این است که withResolvers() معادل است با:


let resolve, reject;
const promise = new Promise((res, rej) => {
  resolve = res;
  reject = rej;
});
// use resolve and reject to control the promise

در قطعه بالا، ما مراجع resolve و reject را در محدوده ضمیمه اعلام می کنیم، سپس از آنها در داخل متن Promise استفاده می کنیم. برای ارجاع به آرگومان های resolve و reject برگشت تماس بگیرید. به این ترتیب، ما از خارج از خود تماس پاسخگوی تماس، کنترل می کنیم.

نحو Promise.withResolvers() فشرده تر است و ما مجبور نیستیم resolve و reject را جداگانه اعلام کنیم. با این روش، می‌توانیم دقیقاً همان عملکرد بالا را مانند این بنویسیم:


let { promise, resolve, reject } = Promise.withResolvers();

ماهیت این قابلیت این است که زمانی که نیاز به دسترسی خارجی به resolve() و reject() دارید، از آن استفاده می‌کنید. این یک سناریوی خیلی رایج نیست اما اتفاق می افتد. بیایید یک مثال ساده را در نظر بگیریم:


function race(operation1, operation2) {
  const { racePromise, resolve, reject } = Promise.withResolvers();

  operation1().then(resolve).catch(reject);
  operation2().then(resolve).catch(reject);

  return racePromise;
}

function fetchData1() {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Data from source 1"), 1000);
  });
}

function fetchData2() {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Data from source 2"), 500);
  });
}

race(fetchData1, fetchData2)
  .then((data) => console.log("Winner:", data))
  .catch((error) => console.error("Error:", error));

در اینجا، ما دو عملیات داریم، fetchData1() و fetchData2()، که وعده‌ها را برمی‌گرداند. آنها تایم اوت ها را اجرا می کنند و fetchData2() همیشه در ۵۰۰ میلی ثانیه سریع ترین است. ما از withResolvers() در تابع race() استفاده می کنیم تا توابع resolve و reject را آشکار کنیم. سپس این توابع توسط یک وعده جدید به نام racePromise استفاده می شود.

سپس از توابع resolve و reject برای پاسخ به دو عملیات fetchData استفاده می کنیم. این جالب است زیرا می‌بینید که ما حتی به racePromise پاسخ تماس نمی‌دهیم. در عوض، ما وعده را از خارج کنترل می کنیم. ما از آن کنترل برای پیوند دادن نتیجه دو وعده دیگر به racePromise استفاده می کنیم.

این یک مثال ساختگی است و تا حدودی غیر واقعی است زیرا دو وعده مسابقه همزمان شروع نمی شوند. نکته این است که ماهیت چگونگی و زمان استفاده از withResolvers() را نشان دهیم.

Object.groupBy و Map.groupBy

روش مفید groupBy روشی سریع برای سازماندهی مجموعه ها بر اساس مقدار رشته است. این یک روش ثابت در Object و Map است که روی مجموعه‌ای آرایه مانند کار می‌کند. متد groupBy() دو آرگومان می گیرد: مجموعه و یک فراخوانی که روی آن عمل می کند. شما یک نمونه شی جدید را دریافت می کنید که دارای مقادیر برچسب رشته به عنوان کلید، و عناصر آرایه مربوطه به عنوان مقدار است.

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

این یک چیز نسبتاً متداول است که در کدنویسی روزمره مطرح می شود. نگاه کردن به یک مثال باید آن را روشن کند. فرض کنید ما مجموعه ای از نژادهای سگ و اندازه آنها داریم:


const dogBreeds = [
  { breed: 'Shih Tzu', size: 'Toy' },
  { breed: 'Leonberger', size: 'Giant' },
  { breed: 'King Charles Spaniel', size: 'Toy' },
  { breed: 'Great Pyrenees', size: 'Giant' },
  { breed: 'Corgi', size: 'Small' },
  { breed: 'German Shepherd', size: 'Large' },
];

حالا، بگویید می‌خواهیم این مجموعه را بر اساس اندازه سازماندهی کنیم. ما می‌خواهیم به مجموعه‌ای از اشیاء برسیم که کلیدها اندازه نژاد و مقادیر مربوط به نژاد سگ است. به طور معمول، ما یک حلقه برای انجام این کار می نویسیم، اما کمی دشوار است. به نظر می رسد باید راه بهتری وجود داشته باشد. اکنون، با groupBy()، وجود دارد:


groupBy() is that better way:

Object.groupBy(dogBreeds, (x) => {
    return x.size;
})

This gives us output like so:

{ "Toy": [
    { "breed": "Shih Tzu", "size": "Toy" },
    { "breed": "King Charles Spaniel", "size": "Toy" }
  ],
  "Giant": [
    { "breed": "Leonberger", "size": "Giant" },
    { "breed": "Great Pyrenees", "size": "Giant" }
  ],
  "Small": [
    { "breed": "Corgi", "size": "Small" }
  ],
  "Large": [
    { "breed": "German Shepherd", "size": "Large" }
  ]
}

این روشی ساده و کاربردی به شما می‌دهد تا مجموعه‌هایی از اشیاء را بر اساس برخی ویژگی‌های خود اشیا گروه‌بندی کنید.

متد groupBy() هر چیزی را که توسط تماس برگشتی برگردانده می شود را می گیرد و به طور خودکار تمام عناصری را که مطابق برابری رشته برابر هستند جمع آوری می کند. اگر مقدار برگشتی یک رشته نباشد، به یک رشته تبدیل می شود. اگر نتوان آن را وادار کرد، با خطا مواجه می‌شود.

Atomics.waitAsync

روش جدید Atomics.waitAsync() برای اشتراک‌گذاری ایمن داده‌ها در سراسر رشته‌های کارگر طراحی شده است. مانند Atomics.wait() موضوع اصلی را مسدود نمی کند. از آنجایی که بین رشته ها استفاده می شود، به کلاس SharedArrayBuffer متکی است.

این کلاس به طور پیش‌فرض در مرورگرهای مدرن غیرفعال است مگر اینکه الزامات امنیتی رعایت شود. اما در Node.js کلاس به طور پیش فرض فعال است.

در اینجا یک مثال ساده برای استفاده در Node آورده شده است. توجه داشته باشید که واردات در Node تعبیه شده است، بنابراین نیازی به نصب NPM نیست (اما توجه داشته باشید که عبارت import این است):


// asyncWait.js
const { Worker, isMainThread, parentPort } = require('worker_threads');

const sharedBuffer = new SharedArrayBuffer(4); 
const int32Array = new Int32Array(sharedBuffer);

if (isMainThread) {
  const worker = new Worker(__filename);

  async function waitForMessage() {
    const initialValue = 0;
    const result = await Atomics.waitAsync(int32Array, 0, initialValue);
    if (result.async) {
      console.log("Message received from worker:", int32Array[0]);
    } else {
      console.error("Timeout waiting for worker message");
    }
  }

  waitForMessage(); 
} else {
  setTimeout(() => {
    Atomics.store(int32Array, 0, 1);
  }, ۲۰۰۰); 
}

برای اجرای این برنامه، فقط وارد کنید: $ node asyncWait.js

برنامه یک SharedArrayBuffer (در اطراف یک int32Array پیچیده شده است) را اعلام می کند و سپس بررسی می کند که آیا ما در رشته اصلی هستیم یا خیر. اگر نخ اصلی باشد، نخ کارگری ایجاد می کنیم. (اگر با موضوعات کارگری تازه کار هستید، اینم یک مقدمه خوب< /a>.)

رشته اصلی از طریق تماس Atomics.waitAsync() منتظر به‌روزرسانی از کارگر می‌ماند. سه آرگ waitAsync(1، ۲، ۳) عبارتند از:

  1. آرایه مشترک (int32Array): فضای حافظه مشترک.
  2. عنصر برای تماشا (۰): نمایه آرایه ای که باید منتظر ماند.
  3. مقدار اولیه (initialValue = 0): فقط در صورتی که این مقدار متفاوت است به رشته اصلی اطلاع دهید (به عنوان مثال، اگر کارگر مقدار را روی مقدار اولیه ۰ قرار دهد، اعلان رخ نخواهد داد) .

String.isWellFormed & String.toWellFormed 

ورودی کاربر، داده‌های بد، و اشکالات شبکه، همه منابع رشته‌های نادرست هستند. String.isWellFormed یک بررسی سلامت عقل است. تعیین می کند که آیا یک رشته UTF-16 معتبر است یا خیر. UTF-16 کدگذاری خود جاوا اسکریپت است، بنابراین String.isWellFormed() اطمینان حاصل می کند که یک رشته داده شده چیزی است که جاوا اسکریپت می تواند مدیریت کند:


const string1 = "Hello, InfoWorld!";

const string2 = "Hello, \uD800world!";

console.log(string1.isWellFormed()); // Output: true (well-formed)
console.log(string2.isWellFormed()); // Output: false (malformed)

می‌توانید در این بخش از مرجع موزیلا. افراد بد در رمزگذاری UTF-16 به عنوان "جانشین تنها" شناخته می شوند.

شریک فعال String.isWellFormed، String.toWellFormed یک رشته داده شده را به چیزی معتبر تبدیل می کند. هر جانشین تنها یافت شده با U+FFFD، نویسه علامت سوال الماس سیاه جایگزین می شود: �.


"Hello, \uD800world!".toWellFormed()
// outputs: 'Hello, �world!'

نتیجه گیری

ما مجموعه خوبی از ویژگی‌های جدید در ECMAScript 2024 داریم. Promise.withResolvers() و Atomics.waitAsync() موارد استفاده پیشرفته‌تری هستند، در حالی که < code>groupBy یک افزودنی راحت است که اغلب به کار می آید و روش های رشته ای جدید برای موقعیت های خاص عالی هستند. همه این ویژگی‌ها برای جاوا اسکریپت در مرورگرها و محیط‌های سمت سرور پشتیبانی می‌شوند، بنابراین می‌توانید از امروز شروع به استفاده از آنها کنید.