বেনিয়ামিনের উত্তরটি এই সমস্যাটি সমাধানের জন্য দুর্দান্ত বিমূর্ততা সরবরাহ করে, তবে আমি কম বিমূর্ত সমাধানের জন্য আশা করছিলাম। এই সমস্যাটি সমাধান করার সুস্পষ্ট উপায় হ'ল .catch
অভ্যন্তরীণ প্রতিশ্রুতিগুলি সহজভাবে কল করা এবং তাদের কলব্যাক থেকে ত্রুটি ফিরিয়ে দেওয়া।
let a = new Promise((res, rej) => res('Resolved!')),
b = new Promise((res, rej) => rej('Rejected!')),
c = a.catch(e => { console.log('"a" failed.'); return e; }),
d = b.catch(e => { console.log('"b" failed.'); return e; });
Promise.all([c, d])
.then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
.catch(err => console.log('Catch', err));
Promise.all([a.catch(e => e), b.catch(e => e)])
.then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
.catch(err => console.log('Catch', err));
এটি আরও একধাপ এগিয়ে নিয়ে যাওয়া, আপনি জেনেরিক ধরা হ্যান্ডলারটি দেখতে দেখতে দেখতে এটি লিখতে পারেন:
const catchHandler = error => ({ payload: error, resolved: false });
তাহলে আপনি করতে পারেন
> Promise.all([a, b].map(promise => promise.catch(catchHandler))
.then(results => console.log(results))
.catch(() => console.log('Promise.all failed'))
< [ 'Resolved!', { payload: Promise, resolved: false } ]
এটির সাথে সমস্যাটি হ'ল ধরা পড়া মানগুলির নন-ক্যাচড মানগুলির চেয়ে আলাদা ইন্টারফেস থাকবে, তাই এটি পরিষ্কার করার জন্য আপনি এমন কিছু করতে পারেন:
const successHandler = result => ({ payload: result, resolved: true });
সুতরাং এখন আপনি এটি করতে পারেন:
> Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
.then(results => console.log(results.filter(result => result.resolved))
.catch(() => console.log('Promise.all failed'))
< [ 'Resolved!' ]
তারপরে এটি শুকনো রাখতে, আপনি বেঞ্জামিনের উত্তর পেতে পারেন:
const reflect = promise => promise
.then(successHandler)
.catch(catchHander)
এখন এটি দেখতে কেমন দেখাচ্ছে
> Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
.then(results => console.log(results.filter(result => result.resolved))
.catch(() => console.log('Promise.all failed'))
< [ 'Resolved!' ]
দ্বিতীয় সমাধানের সুবিধাগুলি হ'ল এটি বিমূর্ত এবং DRY। খারাপ দিকটি হ'ল আপনার আরও কোড রয়েছে এবং জিনিসগুলিকে সামঞ্জস্যপূর্ণ করার জন্য আপনার সমস্ত প্রতিশ্রুতি প্রতিফলিত করতে হবে you
আমি আমার সমাধানটিকে স্পষ্ট এবং কেআইএসএস হিসাবে চিহ্নিত করব তবে সত্যই কম শক্ত। ইন্টারফেস গ্যারান্টি দেয় না যে আপনি প্রতিশ্রুতিটি সফল হয়েছে কিনা তা ব্যর্থ হয়েছে কিনা তা আপনি ঠিক জানেন।
উদাহরণস্বরূপ আপনার এটি থাকতে পারে:
const a = Promise.resolve(new Error('Not beaking, just bad'));
const b = Promise.reject(new Error('This actually didnt work'));
এটি ধরা পড়বে না a.catch
, তাই
> Promise.all([a, b].map(promise => promise.catch(e => e))
.then(results => console.log(results))
< [ Error, Error ]
কোনটি মারাত্মক এবং কোনটি ছিল তা বলার উপায় নেই। যদি তা গুরুত্বপূর্ণ হয় তবে আপনি প্রয়োগ করতে চান এবং এটি ইন্টারফেস করতে চান যা সফল হয়েছে কিনা (যা reflect
করে) তা ট্র্যাক করে।
আপনি যদি কেবল ত্রুটিগুলি নিখুঁতভাবে পরিচালনা করতে চান, তবে আপনি কেবল ত্রুটিগুলি অনির্ধারিত মান হিসাবে বিবেচনা করতে পারেন:
> Promise.all([a.catch(() => undefined), b.catch(() => undefined)])
.then((results) => console.log('Known values: ', results.filter(x => typeof x !== 'undefined')))
< [ 'Resolved!' ]
আমার ক্ষেত্রে, ত্রুটিটি বা এটি কীভাবে ব্যর্থ হয়েছিল তা আমার জানা দরকার না - আমার মূল্য আছে কি না তা কেবল যত্নশীল। প্রতিশ্রুতি উত্পন্ন ফাংশনটি নির্দিষ্ট ত্রুটি লগ করার বিষয়ে উদ্বিগ্ন হতে দেব।
const apiMethod = () => fetch()
.catch(error => {
console.log(error.message);
throw error;
});
এইভাবে, বাকি অ্যাপ্লিকেশনগুলি যদি এটি চায় তবে এটির ত্রুটিটিকে উপেক্ষা করতে পারে এবং এটি চাইলে এটিকে অপরিজ্ঞাত মান হিসাবে গণ্য করতে পারে।
আমি চাই যে আমার উচ্চ স্তরের ফাংশনগুলি নিরাপদে ব্যর্থ হয় এবং এর নির্ভরতা কেন ব্যর্থ হয় তার বিশদ সম্পর্কে চিন্তা না করে এবং আমি যখন ট্রেড অফ করতে হয় তখন আমি ডিআইওয়াইয়ের চেয়েও কেআইএসএসকেই বেশি পছন্দ করি - যা শেষ পর্যন্ত আমি ব্যবহার না করা বেছে নিয়েছিলাম reflect
।