কবে। তারপর (সাফল্য, ব্যর্থ) প্রতিশ্রুতির প্রতিরোধক হিসাবে বিবেচিত হয়?


188

আমি কটাক্ষপাত ছিল Bluebird প্রতিশ্রুতি প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী , যেখানে এটি উল্লেখ করেছেন যে .then(success, fail)একটি antipattern হয় । চেষ্টা এবং ধরা হিসাবে আমি এর ব্যাখ্যাটি বেশ বুঝতে পারি না। এই নিম্নলিখিত কি ভুল?

some_promise_call()
.then(function(res) { logger.log(res) }, function(err) { logger.log(err) })

দেখে মনে হচ্ছে উদাহরণটি নীচেরটিকে সঠিক উপায়ে পরামর্শ দিচ্ছে।

some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })

পার্থক্য কি?


1
then().catch()আরও পাঠযোগ্য, কারণ আপনার কমা অনুসন্ধান এবং তদন্ত করার দরকার নেই সাফল্য বা ব্যর্থ শাখার জন্য এই কলব্যাক।
ক্রিজিসটফ সাফজানভস্কি

7
@ কেভিনব: অনেক পার্থক্য রয়েছে, উত্তরগুলি দেখুন
বার্গি

12
@ ক্রিজিস্ফটফসফজানভস্কি - 'আরও ভাল দেখায়' যুক্তি দ্বারা বিধ্বস্ত। সম্পূর্ণ ভুল!
আন্দ্রে পোপভ

6
দ্রষ্টব্য: আপনি যখন ব্যবহার করছেন .catch, আপনি জানেন না কোন পদক্ষেপটি সমস্যার সৃষ্টি করেছে - শেষের ভিতরে thenবা অন্য কোথাও প্রতিশ্রুতি শৃঙ্খলাবদ্ধ। সুতরাং এটির নিজস্ব অসুবিধা আছে।
প্রাণবন্ত- t

2
আমি সর্বদা প্রতিশ্রুতি ফাংশন নাম যোগ করুন। তারপর () প্যারাম এটি পঠনযোগ্য অর্থাতsome_promise_call() .then(function fulfilled(res) { logger.log(res) }, function rejected(err) { logger.log(err) })
শেন রোওট

উত্তর:


215

পার্থক্য কি?

.then()কল একটি প্রতিশ্রুতি যে ক্ষেত্রে কলব্যাক করার সময় একটি ত্রুটি ছোঁড়া বাতিল করা হবে ফিরে আসবে। এর অর্থ, যখন আপনার সাফল্য loggerব্যর্থ হয়, ত্রুটিটি নিম্নলিখিত .catch()কলব্যাকটিতে পৌঁছে দেওয়া হত , তবে সেই failকলব্যাকের সাথে নয় যা এর সাথে চলে success

এখানে একটি নিয়ন্ত্রণ প্রবাহ ডায়াগ্রাম রয়েছে:

দুটি আর্গুমেন্টের সাথে ততক্ষণের প্রবাহের চিত্রটি নিয়ন্ত্রণ করুন তারপরে চেইন ধরার প্রবাহ চিত্রটি নিয়ন্ত্রণ করুন

এটি সিঙ্ক্রোনাস কোডে প্রকাশ করতে:

// some_promise_call().then(logger.log, logger.log)
then: {
    try {
        var results = some_call();
    } catch(e) {
        logger.log(e);
        break then;
    } // else
        logger.log(results);
}

দ্বিতীয়টি log(যা প্রথম যুক্তির মতো .then()) কেবলমাত্র তখনই কার্যকর করা হবে যদি কোনও ব্যতিক্রম ঘটে না happened লেবেলযুক্ত ব্লক এবং breakবিবৃতিটি কিছুটা বিশৃঙ্খলা বোধ করে, এটি আসলে পাইথনের try-except-elseজন্য যা ছিল (প্রস্তাবিত পড়া!)।

// some_promise_call().then(logger.log).catch(logger.log)
try {
    var results = some_call();
    logger.log(results);
} catch(e) {
    logger.log(e);
}

catchএটির এছাড়াও সাফল্য এটির কল থেকে ব্যতিক্রম হ্যান্ডেল করবে।

পার্থক্য জন্য অনেক।

চেষ্টা এবং ধরা হিসাবে আমি এর ব্যাখ্যাটি বেশ বুঝতে পারি না

যুক্তিটি হ'ল সাধারণত আপনি প্রক্রিয়াজাতকরণের প্রতিটি ধাপে ত্রুটিগুলি ধরতে চান এবং এটি আপনাকে শিকলগুলিতে ব্যবহার করা উচিত নয়। প্রত্যাশাটি হ'ল আপনার কাছে কেবলমাত্র একটি চূড়ান্ত হ্যান্ডলার রয়েছে যা সমস্ত ত্রুটিগুলি পরিচালনা করে - আপনি যখন "অ্যান্টিপ্যাটার্ন" ব্যবহার করেন তখনকার কিছু কলব্যাকের ত্রুটিগুলি পরিচালনা করা হয় না।

তবে, এই নিদর্শনটি আসলে খুব কার্যকর: আপনি যখন ঠিক এই পদক্ষেপে ঘটেছিল ত্রুটিগুলি পরিচালনা করতে চান এবং যখন কোনও ত্রুটি ঘটেনি তখন আপনি সম্পূর্ণ আলাদা কিছু করতে চান - যখন ত্রুটিটি অপরিবর্তনযোগ্য নয় rable সচেতন হন যে এটি আপনার নিয়ন্ত্রণ প্রবাহকে শাখা করছে । অবশ্যই, এটি কখনও কখনও পছন্দসই হয়।


এই নিম্নলিখিত কি ভুল?

some_promise_call()
.then(function(res) { logger.log(res) }, function(err) { logger.log(err) })

যে আপনি আপনার কলব্যাক পুনরাবৃত্তি ছিল। আপনি বরং চান

some_promise_call()
   .catch(function(e) {
       return e; // it's OK, we'll just log it
   })
   .done(function(res) {
       logger.log(res);
   });

আপনি .finally()এই জন্য ব্যবহার বিবেচনা করতে পারেন ।


7
এটি কয়েক দিনের মধ্যে পড়েছি এটি সবচেয়ে সহায়ক ব্যাখ্যা (এবং আমি প্রচুর পড়েছি)। আমি কতটা কৃতজ্ঞ তা আমি ব্যাখ্যা করতে পারি না! :) আমি মনে করি আপনার দুজনের মধ্যে আরও পার্থক্য জাগানো উচিত, এটি সাফল্যের ফাংশনের অভ্যন্তরেও ত্রুটিগুলি ধরা.catch দেবে .. ব্যক্তিগতভাবে, আমি এটিকে অত্যন্ত ভুল বলে মনে করি যে আপনি একটি ত্রুটি-এন্ট্রি পয়েন্ট দিয়ে শেষ করেছেন, যা একাধিক ত্রুটি পেতে পারে একাধিক ক্রিয়া, তবে এটি আমার সমস্যা। যাইহোক - তথ্যের জন্য ধন্যবাদ! আপনার কাছে কোনও অনলাইন যোগাযোগের সরঞ্জাম নেই যা আপনি ভাগ করতে ইচ্ছুক তাই আমি আরও কিছু জিনিস জিজ্ঞাসা করতে পারি? : পি
আন্দ্রে পোপভ

2
আমি আশা করি এটি আপনাকে এখানে আরও কিছু উত্সাহ দিচ্ছে। অবশ্যই Promiseএই সাইটের গুরুত্বপূর্ণ মেকানিকের সেরা ব্যাখ্যাগুলির মধ্যে একটি ।
প্যাট্রিক রবার্টস 21

2
.done()মান অংশ নয়, তাই না? কমপক্ষে এমডিএন সেই পদ্ধতিটি তালিকাভুক্ত করে না। এটি সহায়ক হবে।
ygoe 31'19

1
নিঃসন্দেহে doneএটি একটি ব্লুবার্ড জিনিস যা মূলত then+ আনহানডেল-প্রত্যাখ্যান সনাক্তকরণের দ্বারা অবচিত হয়েছিল ।
বার্গি

1
কালারব্লাইন্ডের কেবল একটি নোট: চিত্রগুলি কোনও অর্থ দেয় না :)
বেনি কে

37

দু'জন একরকম নয়। পার্থক্যটি হ'ল প্রথম উদাহরণটি আপনার successহ্যান্ডলারের মধ্যে ফেলে দেওয়া ব্যতিক্রমটিকে ধরবে না । সুতরাং যদি আপনার পদ্ধতিতে কেবল কখনও সমাধান হওয়া প্রতিশ্রুতি ফিরে আসা উচিত, যেমনটি প্রায়শই ঘটে থাকে, আপনার একটি ট্রিলিং catchহ্যান্ডলারের প্রয়োজন (বা অন্য thenকোনও খালি successপ্যারামিটার সহ)। অবশ্যই, এটি thenএমনও হতে পারে যে আপনার হ্যান্ডলার এমন কোনও কিছু না করে যা সম্ভাব্যরূপে ব্যর্থ হতে পারে, এক ক্ষেত্রে 2-পরামিতি ব্যবহার thenকরা ভাল be

তবে আমি বিশ্বাস করি আপনি যে thenপাঠ্যটির সাথে লিঙ্ক করেছেন তার বিন্দুটি হ'ল অবিচ্ছিন্ন পদক্ষেপের একগুচ্ছ চেইন করার দক্ষতায় কলব্যাক্সের বিপরীতে বেশিরভাগ কার্যকর এবং আপনি যখন বাস্তবে এটি করেন, 2-প্যারামিটার ফর্মটি thenসূক্ষ্মভাবে প্রত্যাশা মতো আচরণ করে না , উপরের কারণে মিড-চেইন ব্যবহার করার সময় এটি বিশেষত প্রতিরোধক।

যে কেউ প্রচুর জটিল অ্যাসিঙ্ক স্টাফ করেছেন এবং আমি স্বীকার করার চেয়ে যত্নের চেয়ে এইরকম কোণে ঝাঁপিয়ে পড়েছি, আমি সত্যিই এই বিরোধী-নিদর্শন এড়ানো এবং পৃথক হ্যান্ডলার পদ্ধতির সাথে যাওয়ার পরামর্শ দিই।


18

উভয়ের সুবিধাগুলি এবং অসুবিধাগুলি দেখে আমরা একটি গণনা করতে পারি যে পরিস্থিতিটির জন্য উপযুক্ত কিনা। প্রতিশ্রুতি বাস্তবায়নের এ দুটি প্রধান পন্থা। উভয় এটির প্লাস এবং বিয়োগ রয়েছে

অ্যাপ্রোচ ধরুন

some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })

সুবিধাদি

  1. সমস্ত ত্রুটিগুলি একটি ক্যাচ ব্লক দ্বারা পরিচালিত হয়।
  2. এমনকি তৎকালীন ব্লকে কোনও ব্যতিক্রম ধরা পড়ে।
  3. একাধিক সাফল্য কলব্যাকের শৃঙ্খলা

অসুবিধেও

  1. শৃঙ্খলার ক্ষেত্রে বিভিন্ন ত্রুটি বার্তা প্রদর্শন করা কঠিন হয়ে পড়ে।

সাফল্য / ত্রুটি পদ্ধতির

some_promise_call()
.then(function success(res) { logger.log(res) },
      function error(err) { logger.log(err) })

সুবিধাদি

  1. আপনি সূক্ষ্ম দানযুক্ত ত্রুটি নিয়ন্ত্রণ পান।
  2. আপনার বিভিন্ন ধরণের ত্রুটি যেমন ডিবি ত্রুটি, 500 ত্রুটি ইত্যাদির জন্য সাধারণ ত্রুটি পরিচালনা করার ফাংশন থাকতে পারে etc.

Disavantages

  1. catchযদি আপনি সাফল্য কলব্যাকের মাধ্যমে ছুঁড়ে দেওয়া ত্রুটিগুলি পরিচালনা করতে চান তবে আপনার আর একটি প্রয়োজন হবে

যে কারও জন্য কেবল একটি লগ ফাইল ব্যবহার করে প্রোডাকশন সমস্যাগুলি ডিবাগ করা দরকার তার জন্য আমি সাফল্য / ত্রুটি পদ্ধতির পছন্দ করি কারণ এটি একটি কার্যকারিতা ত্রুটি শৃঙ্খলা তৈরি করার ক্ষমতা দেয় যা আপনার অ্যাপের প্রস্থান সীমানায় লগ ইন করতে পারে।
শেন রোওট

প্রশ্ন। আসুন আমি বলি যে আমি একটি অ্যাসিঙ্ক কল করব যা কয়েকটি জিনিসের মধ্যে একটি করে: 1) সাফল্যের সাথে রিটার্ন দেয় (2xx স্ট্যাটাসকোড), 2) অসফলভাবে ফিরে আসে (4XX বা 5xx কোড) তবে সে অনুযায়ী প্রত্যাখ্যান করা হয়নি, 3) বা মোটেও ফিরে আসে না ( ইন্টারনেট সংযোগ বন্ধ আছে)। কেস # 1 এর জন্য,। সাফল্যের কলব্যাকটি হিট হয়েছে। কেস # 2 এর জন্য।। এ ত্রুটি কলব্যাক হিট হয়েছে। কেস # 3 এর জন্য .কেচ বলা হয়। এটি সঠিক বিশ্লেষণ, তাই না? কেস # 2 সর্বাধিক জটিল বিসি প্রযুক্তিগতভাবে 4XX বা 5xx একটি প্রত্যাখ্যান নয়, এটি এখনও সফলভাবে ফিরে আসে। সুতরাং, আমাদের এটি .টির মধ্যে পরিচালনা করতে হবে। .... আমার বোধগম্যতা কি সঠিক?
বেনিয়ামিন হফম্যান

"কেস # 2 এর জন্য, ত্রুটিতে কলব্যাক .টি হিট হয়েছে case - এটি কীভাবে আনতে কাজ করে
#WebDeveloper

2

সহজ ব্যাখ্যা:

ES2018 এ

অনারেক্টেড যুক্তি দিয়ে ক্যাচ পদ্ধতিটি যখন ডাকা হয় তখন নীচের পদক্ষেপগুলি নেওয়া হয়:

  1. প্রতিশ্রুতি এই মান হতে দিন।
  2. ফিরবেন? আহ্বান (প্রতিশ্রুতি, "তারপর", «অপরিজ্ঞাত, অনারেক্টেড ected)।

এর মানে:

promise.then(f1).catch(f2)

সমান

promise.then(f1).then(undefiend, f2)

1

ব্যবহারের ফলে .then().catch()আপনি প্রতিশ্রুতিবদ্ধ চেইন সক্ষম করতে পারবেন যা একটি কার্যপ্রবাহ পরিপূর্ণ করতে প্রয়োজনীয়। আপনাকে ডাটাবেস থেকে কিছু তথ্য পড়তে হবে তবে আপনি এটিকে একটি এসিঙ্ক এপিআইতে দিতে চান তারপরে আপনি প্রতিক্রিয়াটি হেরফের করতে চান। আপনি প্রতিক্রিয়াটি আবার ডাটাবেসে ঠেলাতে পারেন। আপনার ধারণার সাহায্যে এই সমস্ত ওয়ার্কফ্লো পরিচালনা করা করণীয় তবে পরিচালনা করা খুব কঠিন। আরও ভাল সমাধানটি then().then().then().then().catch()হ'ল যা একবারে একবারে সমস্ত ত্রুটি গ্রহণ করে এবং আপনাকে কোডটির রক্ষণাবেক্ষণযোগ্যতা রাখতে দেয় ।


0

প্রতিশ্রুতিতে চেইন সাফল্য এবং ব্যর্থতা হ্যান্ডলারটি ব্যবহার then()এবং catch()সহায়তা করে। catch()প্রতিশ্রুতি দ্বারা ফিরে কাজ করে then()। এটি পরিচালনা করে,

  1. যদি প্রতিশ্রুতি বাতিল হয়। ছবিতে # 3 দেখুন
  2. তত্ক্ষণাত () এর সাফল্য হ্যান্ডলারে ত্রুটি ঘটলে, নীচের 4 থেকে 7 রেখাটির মধ্যে। ছবিতে # ২ ক দেখুন (ব্যর্থ কলব্যাক এটি then()পরিচালনা করে না))
  3. ততক্ষণে () এর ব্যর্থতা হ্যান্ডলারে ত্রুটি ঘটলে, নীচে 8 নম্বর লাইন। ছবিতে # 3.b দেখুন।

1. let promiseRef: Promise = this. aTimetakingTask (false); 2. promiseRef 3. .then( 4. (result) => { 5. /* successfully, resolved promise. 6. Work on data here */ 7. }, 8. (error) => console.log(error) 9. ) 10. .catch( (e) => { 11. /* successfully, resolved promise. 12. Work on data here */ 13. });

এখানে চিত্র বর্ণনা লিখুন

দ্রষ্টব্য : অনেক সময়, ব্যর্থতা হ্যান্ডলার সংজ্ঞায়িত করা হতে পারে যদি catch()ইতিমধ্যে লিখিত হয়। সম্পাদনা করুন: reject()invoking মধ্যে ফলাফলের catch()শুধুমাত্র যদি ভুল হ্যান্ডলার then()হয় না সংজ্ঞায়িত। ছবিতে # 3 নোট করুন catch()। # 8 এবং 9 লাইনে হ্যান্ডলার সংজ্ঞায়িত না হলে এটি আহ্বান করা হয়।

এটি বোধগম্য হয় কারণ then()কলব্যাক যত্ন নিলে যদি প্রতিশ্রুতি দিয়ে ফিরে আসে তবে ত্রুটি হয় না।


3 নম্বর থেকে catchকলব্যাকের তীরটি ভুল বলে মনে হচ্ছে।
বার্গি

ধন্যবাদ! তত্ক্ষণাত সংজ্ঞায়িত ত্রুটি কলব্যাক দিয়ে (), এটি চাওয়া হয় না (কোড স্নিপেটে লাইন # 8 এবং # 9)। # 3 দুটি তীরগুলির মধ্যে একটিতে প্রার্থনা করে। এটি বোধগম্য কারণ কারণ ততক্ষণে ফিরে আসা প্রতিশ্রুতিতে কোনও ত্রুটি নেই - যদি কোনও কলব্যাক যত্ন নিচ্ছে। উত্তর সম্পাদিত!
ভেনসিকি

-1

শব্দের পরিবর্তে, ভাল উদাহরণ। নিম্নলিখিত কোড (যদি প্রথম প্রতিশ্রুতি সমাধান হয়):

Promise.resolve()
.then
(
  () => { throw new Error('Error occurs'); },
  err => console.log('This error is caught:', err)
);

অনুরূপ:

Promise.resolve()
.catch
(
  err => console.log('This error is caught:', err)
)
.then
(
  () => { throw new Error('Error occurs'); }
)

কিন্তু প্রত্যাখ্যাত প্রথম প্রতিশ্রুতি দিয়ে, এটি অভিন্ন নয়:

Promise.reject()
.then
(
  () => { throw new Error('Error occurs'); },
  err => console.log('This error is caught:', err)
);

Promise.reject()
.catch
(
  err => console.log('This error is caught:', err)
)
.then
(
  () => { throw new Error('Error occurs'); }
)

4
এটি অর্থবোধ করে না, আপনি দয়া করে এই উত্তরটি সরাতে পারেন? এটি সঠিক উত্তর থেকে বিভ্রান্তিকর এবং বিভ্রান্ত করছে।
অ্যান্ডি রে

অ্যান্ডি রে, এটি বাস্তব প্রয়োগে কোনও অর্থবোধ করে না, তবে প্রতিশ্রুতিগুলির কার্যকারিতাটি বোঝার জন্য তা বোধগম্য হয়।
ktretyak
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.