نکتهٔ اصلی Promiseها رو داری از دست میدی
خلاصهٔ کاملتر
نویسنده اول یادآوری میکنه Promise چیه: بهجای اینکه تابع یه کالبک بگیره، یه مقدار برمیگردونه که نمایندهٔ نتیجهٔ نهایی عملیاته. همین باعث میشه بتونی این شیء رو مثل هر مقدار دیگهای پاس بدی، جمع کنی و ترکیب کنی. ولی به گفتهٔ اون، یه روند نگرانکننده تو کتابخونههای جاوااسکریپت وجود داره: پشتیبانی از Promise اضافه میکنن و اصل ماجرا رو کامل از دست میدن.
اصل ماجرا اینه که تابع همگام دو تا کار مهم میکنه: مقدار برمیگردونه و استثنا پرت میکنه. هر دوش هم دربارهٔ ترکیبپذیریه — خروجی یکی میره ورودی بعدی، و اگه جایی خراب شد، خطا از همهٔ لایهها رد میشه تا برسه به کسی که catch داره. تو دنیای ناهمگام هر دوش رو از دست میدی و میافتی تو callback hell. نویسنده معتقده کل نقطهٔ Promise همینه که این دو تا رو برگردونه.
پس زنجیرهٔ ناهمگام باید دقیقاً موازی نسخهٔ همگامش بشه: خطا از هر مرحلهای بدون کد دستی، خودش میره بالا تا هندلر خطا:
getTweetsFor("domenic") // promise-returning function
.then(function (tweets) {
var shortUrls = parseTweetsForUrls(tweets);
return expandUrlUsingTwitterApi(shortUrls[0]);
})
.then(httpGet)
.then(
function (responseBody) { console.log(responseBody); },
function (error) { console.error("Error:", error); }
);چیزی که این رو ممکن میکنه، پاراگراف دوم اسپک CommonJS Promises/A ست: then باید یه Promise جدید برگردونه. یعنی then مکانیزم چسبوندن کالبک به یه مجموعه نیست، مکانیزم اعمال یه تبدیل روی Promise و ساختن یه Promise تازهست. اگه هندلر مقدار برگردونه، Promise جدید با اون مقدار fulfill میشه؛ اگه استثنا پرت کنه، reject میشه. نویسنده میگه این چهار حالت (مقدار/استثنا، در وضعیت fulfilled/rejected) دقیقاً معادل try/catch همگامان.
مشکل jQuery قبل از نسخهٔ 1.8 این بوده که بهجای ساختن Promise جدید، وضعیت همون قبلی رو تغییر میداده؛ یعنی اگه Promise رو به دو مصرفکننده بدی، میتونن روی هم اثر بذارن. به گفتهٔ نویسنده، jQuery فقط سناریوی اول رو پشتیبانی میکنه و ۲ تا ۴ رو کلاً نداره. نتیجهش اینه که کتابخونههای عمومی نمیتونن به «thenable بودن» اعتماد کنن و مجبور میشن هک بزنن تا شیءهایی که ادای Promise درمیارن رو تشخیص بدن.
راهحلی که نویسنده پیشنهاد میده، مجموعهتست انطباق و بعدش تشکیل Promises/A+ بوده؛ ائتلافی از پیادهسازها که متن اسپک اولیه رو شفاف و تستپذیر کردن. اون Q، RSVP.js و when.js رو بهعنوان پیادهسازیهای سازگار توصیه میکنه و میگه اگه گیر یه Promise ناقص افتادی، هر چه سریعتر با ابزار assimilation (معمولاً به اسم when) تبدیلش کن به یه Promise واقعی.
نکات کلیدی:
- Promise دربارهٔ جمع کردن کالبک نیست، دربارهٔ ترکیبپذیری و بالا رفتن خطاست
- then باید یه Promise جدید برگردونه، نه اینکه وضعیت قبلی رو عوض کنه
- هندلر مقدار برگردونه یعنی fulfill؛ استثنا پرت کنه یعنی reject — معادل try/catch
- Promiseی که این چهار سناریو رو نداشته باشه، عملاً فقط یه جمعکنندهٔ کالبکه
- Promises/A+ همین ابهامها رو شفاف و تستپذیر کرد
- Q، RSVP.js و when.js پیادهسازیهای سازگارن




