وقتی یه خط کد تو رو وارد دنیای جدیدی میکنه!

امشب همینجوری تصمیم گرفتم سورس کد پکیج p-map رو بخونم. این پکیج وقتی استفاده میشه که یه تابع async داشته باشیم (mapper) و بخوایم چند بار با پارامتر های مختلف اون رو اجرا کنیم.

import pMap from 'p-map'; 
import got from 'got';  
const sites = [  
    getWebsiteFromUsername('sindresorhus'), //=> Promise 
    'https://avajs.dev',      
    'https://github.com'
];  

const mapper = async site => {  
    const {requestUrl} = await got.head(site);  
    return requestUrl; 
};  

const result = await pMap(sites, mapper);  

console.log(result); //=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']

وقتی شروع کردم به خوندن تو همون خط های اول چند بار با عبارت Symbol مواجه شدم:

تا حالا با Symbol ها آشنا نشده بودم. البته از کاربردش توی کد و دانش محدودی که از پایتون داشتم تقریبا فهمیدم که به چه دردی میخوره: همونطور که توی مثال بالا دیدید تابع pMap به عنوان اولین پارامترش یک iterable مثل آرایه میگیره. توی خط ۱۲ کد بالا داره چک میکنه که آیا پارامتر اول iterable هست یا نه. ولی بازم برام عجیب بود ولی با یکم تحقیق یکم سر در آوردم.

بیاین اول یکم با خود Symbol ها آشنا بشیم. Symbol هم مثل Number که اعداد رو نشون میده و String که رشته های حرفی رو نشون میده یه نوع از دیتا هست. ولی دقیقا چی رو داره نشون میده؟ جواب یه مقدار یکتا هست! تنها چیزی که در موردش باید بدونید اینه که یه مقدار یکتا و منحصر به فرد هست. میتونید مثل یه عدد خیلی بزرگ مثل 3402894209850295 که همیشه یکتا هست بهش نگاه کنید.

هر بار که تابع Symbol رو اجرا میکنیم، یه مقدار یکتا برامون ساخته میشه. درسته که وقتی تابع toString رو روی اونها اجرا میکنیم یه چیز مشابه رو میبینیم ولی در عمل به هم متفاوت هستند:

const symbol1 = Symbol()
const symbol2 = Symbol()

console.log(symbol1) // Symbol()
console.log(symbol2) // Symbol()

console.log(symbol1 === symbol2) // false

کاربرد اصلیش وقتیه که بخوایم یه key توی یه آبجکت داشته باشیم که مطمئن باشیم یکتا هست.بقیه مباحث از دامنه این مطلب خارجه. میتونید اینجا یکم در موردش بخونید. چنتا مثال ساده هم آخر این ویدیو میتونید ببینید.

قسمت دوم ماجرا iterable ها توی جاوااسکریپت هستند. یادتونه گفتم دانش محدودی که از پایتون داشتم تو فهم اون کد کمکم کرد؟ خب توی پایتون هر چیزی که iterable باشه یا به صورت ساده بشه ازش توی حلقه for استفاده کرد باید یه متد به اسم __iter__ پیاده سازی کنه. این تابع یه iterator برمیگردونه که حلقه for ازش استفاده میکنه.

ظاهرا توی جاوااسکریپت هم همچین خبر هایی هست. هر چیزی که توی جاوااسکریپت iterable باشه باید متد iterator@@ رو پیاده سازی کنه. این متد یه iterator برمیگردونه که حلقه for ازش استفاده میکنه. مثلا آرایه ها این متد رو به صورت پیشفرض دارند. (اطلاعات بیشتر)

اگر توی devtools مرورگرتون یه آرایه بسازید و از همونجا property هاش رو بررسی کنید یه همچین چیزی میبینید:

همونطور که میبینید، Symbol.iterator همون تابع iterator@@ هست که تعریفش رو شنیدیم. دقت کنید که به صورت یه Symbol تعریف شده. تو جاوااسکریپت یه لیست خاص از Symbol ها هستند که به اسم well-known symbols شناخته میشن. Symbol.iterator هم یکی از اون هاست که یه جورایی به عنوان id تابع iterator@@ استفاده میده. در نتیجه اگر بخوایم به تابع iterator@@ یه آرایه دسترسی داشته باشیم باید از این Sybmol استفاده کنیم:

الان اون خط از کد برام روشن شد.

if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) {...}

اگر پارامتر اول که اسمش iterable هست Symbol.iterator رو نداشت یعنی اینکه iterable نبود ینی یه جای میلنگه و یه ارور میفرسته. قضیه asyncIterator هم مثل همونه که به خودتون میسپارم.

در نتیجه چند ساعت از وقتم رو همین یه خط کد گرفت (شامل نوشتن این پست هم میشه). گیتهاب جای فوق العاده ای برای یادگیریه. خیلی از پکیج هایی که استفاده میکنید مثل این ممکنه فقط یه فایل داشته باشند و خوندنش راحته. دیدن کدش قطعا میتونه خیلی چیزا یادتون بده. یه چیز جالب هم اینه که پکیج p-map هر هفته نزدیک به ۳۰ میلیون بار دانلود میشه! ببینید یه پکیج ساده چقدر میتونه کاربرد داشته باشه.

در ضمن اگر جایی توی مقاله اشتباه فنی داشتم حتما بهم گوشزد کنید:)

نوشته وقتی یه خط کد تو رو وارد دنیای جدیدی میکنه! اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

دیدگاهتان را بنویسید