[Node.js] استفاده از توابع مبتنی بر تماس زمانی که بقیه کد از Promises استفاده می کنند
سلام!
نام من Gaurang است و در 5 سال گذشته با Node.js کار کرده ام. این مقاله بخشی از مجموعه “راهنمای من برای عبور از پیچ و خم پاسخ به تماس ها و قول ها” است. این یک سری 3 قسمتی است که من در مورد نوشتن کدهای ناهمزمان با Node.js صحبت می کنم.
مقالات در سطح متوسط هستند و انتظار می رود که خواننده قبلاً با نحو Node.js و ساختارهای مربوط به برنامه نویسی ناهمزمان در آن آشنایی اولیه داشته باشد. مانند تماسهای برگشتی، وعدهها، و async-wait.
فهرست مطالب
معرفی
Promises در سال 2015 در جاوا اسکریپت معرفی شد – فقط 8 سال قبل از تاریخ نوشتن این مقاله. Async-await در سال 2017 معرفی شد – فقط 6 سال پیش. خیلی وقت پیش نبود. (حداقل برای از بین بردن استفاده از کال بک کافی نیست 😢)
به عنوان یک حرفه ای که کار می کند، اغلب باید با کدهای قدیمی کار کنید. بنابراین، به عنوان یک توسعه دهنده JavaScript/Node.js، خدای ناکرده، ممکن است مجبور شوید زمانی با callbacks کار کنید. و من فرض میکنم که شما به اندازه کافی در معرض تماسهای تلفنی قرار گرفتهاید تا ترس عمومی را که آنها به همراه دارند را درک کنید.
نوشتن کد با پاسخ به تماس زمان بر است. برای کسانی که تجربه قبلی با برنامه نویسی ناهمزمان ندارند، با گاوبازی برای اولین بار تفاوتی ندارد. به همین دلیل، من معتقدم که آنها سعی می کنند به نسخه همگام توابع async بچسبند. اگر مقاله قبلی من در این مجموعه را خوانده باشید، میدانید که این رویکرد بیشتر از اینکه مفید باشد آسیبرسان است.
نظر شخصی من این است که بهترین راه برای مقابله با توابع مبتنی بر تماس، تبدیل آنها به توابع بازگشت دهنده است.
فرض کنید، شما در حال کار بر روی یک پروژه مبتنی بر Node.js هستید. شما ماژول های جدیدی ایجاد کردید (ممکن است API ها، کنترلرها، خدمات ابزار و غیره) باشند. همه چیز با استفاده از وعده ها و async-wait. با این حال، برخی از توابع قدیمی وجود دارد که با استفاده از رویکرد برگشت به تماس نوشته شدهاند. شما باید یکی از این تابع ها را فراخوانی کنید، اما نمی خواهید یک جهنم پاسخ به تماس ایجاد کنید.
3 راه برای پیشبرد این کار وجود دارد.
- استفاده کنید
util.promisify
(مورد علاقه من) - یک وعده جدید ایجاد کنید.
- بسته بندی هوشمندی ایجاد کنید که بر اساس نیاز شما می تواند به شما پاسخ تماس یا Promise بدهد
استفاده كردن util.promisify
بسیاری از مردم در مورد این جواهر که در Node.js نسخه 8 معرفی شده است اطلاعی ندارند. اگر تابع مبتنی بر callback قدیمی از سبک استاندارد error-first callback استفاده می کند و callback آخرین آرگومان است، می توانید یک قول ایجاد کنید- بازگشت تابع با استفاده از حداقل کد util.promisify
.
با این حال، باید مراقب استفاده از آن با توابعی باشید که متعلق به یک کلاس/شیء هستند.
اگر در تابع bind تازه کار هستید و مطمئن نیستید که زمینه شی چیست، در اینجا چند منبع عالی وجود دارد که ممکن است به شما کمک کند:
یکی از بهترین چیزها در مورد util.promisify
این است که بدون نقص با روش های کتابخانه بومی Node.js مانند توابع متعلق به ماژول ها کار می کند: fs
، child_process
و غیره می توانید از آن برای قول دادن استفاده کنید setTimeout
همچنین.
ایجاد یک وعده جدید
اگر تابع مبتنی بر تماس از قراردادهای مناسب پیروی نمی کند. یا بنا به دلایلی، util.promisify
برای شما کار نمی کند، همیشه می توانید یک Promise جدید سفارشی ایجاد کنید.
اگر Promise-creation را به صورت درون خطی کثیف به نظر میرسد، میتوانید به یک تابع جداگانه منتقل کنید.
توجه: در اینجا، promisifiedAsyncFunction
از async-await استفاده نمی کند. اما، یک وعده را برمی گرداند. بنابراین، ما باید استفاده کنیم await
در عملکرد اصلی هنگام تماس promisifiedAsyncFunction
اگر تابع مبتنی بر تماس به یک کلاس/شیء تعلق دارد، باید از زمینه مراقبت کنید.
یک پوشش دوگانه Promise/Callback ایجاد کنید
اگر به کد منبع تابع مبتنی بر تماس اصلی دسترسی دارید. و اختیار تغییر آن، می توانید یک لفاف در اطراف آن ایجاد کنید. در صورت ارائه پاسخ به تماس، این پوشش به عنوان یک تابع مبتنی بر تماس عمل خواهد کرد. اگر نه، یک Promise را برمی گرداند.
این پوشش دوگانه به شما امکان می دهد با Promises در کد جدیدی که می نویسید کار کنید. بدون ایجاد مزاحمت در کد قدیمی، جایی که انتظار میرود عملکرد با یک تماس برگشتی کار کند. بنابراین، پشتیبانی از Promise را با سازگاری به عقب برای کدهای قدیمی مبتنی بر تماس ارائه می کند.
قبلا، اگر ماژول صادر می کرد callbackBasedAsyncFunc
تابع، اکنون می تواند آن را صادر کند dualBehaviourWrapper
.
// Previously
module.exports.callbackBasedAsyncFunc = callbackBasedAsyncFunc;
// Now
module.exports.callbackBasedAsyncFunc = dualBehaviourWrapper;
بنابراین، با حداقل تغییر، می توانید پشتیبانی Promise را به یک ماژول قدیمی اضافه کنید. و تمام ماژول های موجود دیگر که در حال فراخوانی هستند callbackBasedAsyncFunc
با ارسال یک تماس برگشتی، تحت تأثیر قرار نگیرید. برد – برد!
ممکن است متوجه شده باشید که بسیاری از کتابخانههای محبوب NPM از عملکردهای خود با رفتار دوگانه پشتیبانی میکنند، در صورتی که از یک callback استفاده میکنند، و در صورت عدم ارسال پاسخ، از Promise برمیگردانند. اگرچه ممکن است اجرای آنها متفاوت باشد. به عنوان مثال، mocha.js
پاورقی:
fs
نسخه 10 Promises API را معرفی کرد که دارای نسخه های مبتنی بر وعده از توابع است. به مستندات نگاهی بیندازید. بنابراین شما نیازی به مبارزه با تماسهای برگشتی یا تبدیل دستی ندارید fs
توابع به موارد مبتنی بر وعده.