ما Developer ها به Magic عادت داریم. بیشتر وقت ها کدی که مینویسیم فقط میخوایم کار کنه. اما چطور کار کردن اون کد خیلی اهمیتی نداره تا وقتی که کدمون کار میکنه. حالا چه به صورت جادویی کار کنه چه با جزئیات کامل بدونیم پشت پرده چخبر هست. گاها بعضی از این جادو ها اینقدر پیچیده و ترسناک به نظر میان که اصلا بهشون نزدیک نمیشیم. یکی از این Magic ها Promise ها در #JavaScript هست. اکثرا فکر میکنیم یک چیزی هست که داخل گوشت و وجود #JavaScript فرو رفته و به هیچ عنوان نمیشه تغییرش داد یا اگر هم بشه خیلی سخت هست. کاری به پیاده سازی اصلیش امروز نداریم. امروز بعد از این مقدمه طولانی میخواهیم باهم یاد بگیرم چطور یک Object بسازیم که شبیه به Promise عمل میکنه. یعنی میتونیم await کنیم اون رو با وجود این که اصلا اون Promise نیست و یک Object ساده هست. به این کد پایین دقت کنید.
معمولا اولین واکنش افراد به این تکه کد "WTF" هست. داستان از این قرار هست که خیلی قبل تر از این که Promise ها به صورت استاندارد وارد #JavaScript بشن پیاده سازی های مختلف ازش وجود داشته و هرکدوم implemention detail خاص خودشون رو داشتن ولی طی گذر زمان بلاخره رسیدن به این interface که الان داریم هر روز باهاش کار میکنیم ( تقریبا شبیه به وضعیت decorator ها و پروپزوال مربوط بهش ). بزارید یکم بیشتر وارد داستان بشیم.
برای این که بتونیم یک object رو await کنیم لزوما نیازی نداره حتما یک instance از Promise باشد. بلکه هر object که Promise-like باشد میتواند await بشود. این تعریف دقیقا تعریف Duck-typing هست که قبلا مفصل درموردش حرف زدیم. حالا سوال پیش میاد که Promise-like یعنی چی؟
- هر class که thanable interface را implement کند میتوان آن را await کرد.
پس میتونیم نتیجه بگیریم که همه Promise ها thenable هستند ولی همه thenable ها Promise نیستند.
حالا میرسیم که thanable interface چیست؟ در ساده ترین حالت دقیقا مثال بالا رو در نظر بگیرد. یک object یا class که then method رو که با دوتا argument که هردو callback هستن یکی برای وقتی که reject شده و یکی برای وقتی resolve میشه invoke میشود و ما میتونیم با اون دوتا رفتاری که Promise-like هست رو از خودمون نشون بدیم.
حالا این ویژگی به ما اجازه داده که پکیج های معروفی مثل promise-retry ببینیم یا حتی یکم تلاش کنیم به کمک Promise-like ها در ES5 بتونیم چیزی شبیه بهش رو داشته باشیم که البته این موضوع خودش یک بحث دیگس اگر دوست دارید نگاهی به promise-polyfill یا babel-polyfill بندازید.
این هم پست مربوط به duck typing به نظرم نگاهی بندازید:
https://t.iss.one/NodeMaster/128
const thenable = {
then(resolve, reject) {
setTimeout(() => resolve("Hello from thenable!"), 1000)
},
}
const txt = await thenable
console.log(txt)معمولا اولین واکنش افراد به این تکه کد "WTF" هست. داستان از این قرار هست که خیلی قبل تر از این که Promise ها به صورت استاندارد وارد #JavaScript بشن پیاده سازی های مختلف ازش وجود داشته و هرکدوم implemention detail خاص خودشون رو داشتن ولی طی گذر زمان بلاخره رسیدن به این interface که الان داریم هر روز باهاش کار میکنیم ( تقریبا شبیه به وضعیت decorator ها و پروپزوال مربوط بهش ). بزارید یکم بیشتر وارد داستان بشیم.
برای این که بتونیم یک object رو await کنیم لزوما نیازی نداره حتما یک instance از Promise باشد. بلکه هر object که Promise-like باشد میتواند await بشود. این تعریف دقیقا تعریف Duck-typing هست که قبلا مفصل درموردش حرف زدیم. حالا سوال پیش میاد که Promise-like یعنی چی؟
- هر class که thanable interface را implement کند میتوان آن را await کرد.
پس میتونیم نتیجه بگیریم که همه Promise ها thenable هستند ولی همه thenable ها Promise نیستند.
حالا میرسیم که thanable interface چیست؟ در ساده ترین حالت دقیقا مثال بالا رو در نظر بگیرد. یک object یا class که then method رو که با دوتا argument که هردو callback هستن یکی برای وقتی که reject شده و یکی برای وقتی resolve میشه invoke میشود و ما میتونیم با اون دوتا رفتاری که Promise-like هست رو از خودمون نشون بدیم.
حالا این ویژگی به ما اجازه داده که پکیج های معروفی مثل promise-retry ببینیم یا حتی یکم تلاش کنیم به کمک Promise-like ها در ES5 بتونیم چیزی شبیه بهش رو داشته باشیم که البته این موضوع خودش یک بحث دیگس اگر دوست دارید نگاهی به promise-polyfill یا babel-polyfill بندازید.
این هم پست مربوط به duck typing به نظرم نگاهی بندازید:
https://t.iss.one/NodeMaster/128
Telegram
Node Master
امروز درمورد Duck Typing صحبت میکنیم. این موضوع مربوط به رفتار زبان های dynamic type میباشد. البته این تکنیک در زبان هایی static type هم در حالت های خاصی استفاده میشود. برای درک این موضوع با مثال در #Python شروع میکنیم.
class Duck:
def fly(self):
…
class Duck:
def fly(self):
…
👍11