আমার কি প্রাথমিক সমাধান / প্রত্যাখ্যানের পরে ফিরে আসতে হবে?


262

ধরুন আমার কাছে নিম্নলিখিত কোড রয়েছে।

function divide(numerator, denominator) {
 return new Promise((resolve, reject) => {

  if(denominator === 0){
   reject("Cannot divide by 0");
   return; //superfluous?
  }

  resolve(numerator / denominator);

 });
}

আমার উদ্দেশ্য যদি rejectতাড়াতাড়ি প্রস্থান করার জন্য ব্যবহার করা হয়, তবে আমি কি returnতত্ক্ষণাত পরে আইএনজি অভ্যাসে প্রবেশ করব ?


উত্তর:


370

returnউদ্দেশ্য প্রত্যাখ্যান পর ফাংশন সঞ্চালনের বিনষ্ট, এবং এটি পরে কোড সঞ্চালনের প্রতিরোধ করা হয়।

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {

    if (denominator === 0) {
      reject("Cannot divide by 0");
      return; // The function execution ends here 
    }

    resolve(numerator / denominator);
  });
}

এই ক্ষেত্রে এটি resolve(numerator / denominator);কার্যকর করতে বাধা দেয় , যা কঠোরভাবে প্রয়োজন হয় না। তবে ভবিষ্যতে কোনও সম্ভাব্য ফাঁদ আটকাতে মৃত্যুদণ্ড কার্যকর করা স্থগিত করা আরও ভাল। এছাড়াও, অযথা চালানো কোডটি রোধ করা ভাল অভ্যাস।

পটভূমি

প্রতিশ্রুতি 3 টির মধ্যে একটিতে হতে পারে:

  1. মুলতুবি - প্রাথমিক অবস্থা। মুলতুবি থেকে আমরা অন্য রাজ্যের যে কোনও একটিতে যেতে পারি
  2. সম্পন্ন - সফল অপারেশন
  3. প্রত্যাখ্যান - ব্যর্থ অপারেশন

যখন কোনও প্রতিশ্রুতি পূর্ণ হয় বা প্রত্যাখ্যাত হয়, তা অনির্দিষ্টকালীন (নিষ্পত্তি) এ অবস্থায় থাকবে। সুতরাং, একটি প্রতিশ্রুতি প্রত্যাখ্যান করা বা প্রত্যাখ্যাত প্রতিশ্রুতি পূরণ করা কার্যকর হবে না।

এই উদাহরণ স্নিপেট দেখায় যে প্রতিশ্রুতি প্রত্যাখ্যান হওয়ার পরেও তা পূরণ হয়েছিল, তবে তা প্রত্যাখ্যান করেই রইল।

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {
    if (denominator === 0) {
      reject("Cannot divide by 0");
    }

    resolve(numerator / denominator);
  });
}

divide(5,0)
  .then((result) => console.log('result: ', result))
  .catch((error) => console.log('error: ', error));

তাহলে আমাদের ফিরতে হবে কেন?

যদিও আমরা কোনও নিষ্পত্তির প্রতিশ্রুতি স্থিতি পরিবর্তন করতে পারি না, প্রত্যাখ্যান করা বা সমাধান করা ফাংশনের বাকী ক্রিয়াকলাপ বন্ধ করে দেয় না। ফাংশনে এমন কোড থাকতে পারে যা বিভ্রান্তিকর ফলাফল তৈরি করবে। উদাহরণ স্বরূপ:

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {
    if (denominator === 0) {
      reject("Cannot divide by 0");
    }
    
    console.log('operation succeeded');

    resolve(numerator / denominator);
  });
}

divide(5, 0)
  .then((result) => console.log('result: ', result))
  .catch((error) => console.log('error: ', error));

এমনকি যদি ফাংশনটিতে এখনই এই জাতীয় কোড না রয়েছে তবে এটি সম্ভাব্য ভবিষ্যতের ফাঁদ তৈরি করে। ভবিষ্যতের রিফ্যাক্টর এই সত্যটি অগ্রাহ্য করতে পারে যে প্রতিশ্রুতি প্রত্যাখ্যানের পরে কোডটি এখনও কার্যকর করা হয়েছে, এবং এটি ডিবাগ করা শক্ত হবে।

সমাধান / প্রত্যাখ্যানের পরে কার্যকর করা বন্ধ করা:

এটি স্ট্যান্ডার্ড জেএস নিয়ন্ত্রণ প্রবাহ স্টাফ।

  • resolve/ এর পরে ফিরে আসুন reject:

  • resolve/ reject- দিয়ে ফিরে আসুন যেহেতু কলব্যাকের ফেরতের মান উপেক্ষা করা হয়, তাই আমরা প্রত্যাখ্যান / সমাধানের বিবৃতি ফিরিয়ে একটি লাইন সংরক্ষণ করতে পারি:

  • একটি / অন্য ব্লক ব্যবহার করে:

returnকোডটি চাটুকার হওয়ায় আমি বিকল্পগুলির একটির ব্যবহার করতে পছন্দ করি ।


28
উল্লেখযোগ্য যে, কোডটি আসলে returnসেখানে থাকলে অন্যভাবে আচরণ করবে না বা না কারণ একবার প্রতিশ্রুতিবদ্ধ রাজ্যটি সেট হয়ে resolve()গেলে, কল করার পরে কল করা কিছু পরিবর্তন করা যায় reject()না, কিছু অতিরিক্ত সিপিইউ চক্র ব্যতীত আর কিছু করা হয় না। আমি নিজেই returnএকটি কোড পরিষ্কার-পরিচ্ছন্নতা এবং দক্ষতার দৃষ্টিকোণ থেকে সঠিকভাবে ব্যবহার করব, তবে এই নির্দিষ্ট উদাহরণে এটি প্রয়োজন হয় না।
jender00

1
Promise.try(() => { })নতুন প্রতিশ্রুতির পরিবর্তে ব্যবহার করার চেষ্টা করুন এবং কলগুলি / সমাধান প্রত্যাখ্যান করা এড়ানো। পরিবর্তে আপনি কেবল লিখতে পারতেন একটি প্রতিশ্রুতি বন্ধ করার জন্য পাশাপাশি সমস্যাযুক্ত / চেষ্টা করুন / ব্লকগুলিতে আবদ্ধ প্রতিশ্রুতিগুলি দূর করার উপায় হিসাবে return denominator === 0 ? throw 'Cannot divide by zero' : numerator / denominator; আমি ব্যবহার করতে পারি Promise.try
কিংডাঙ্গো

2
এটি জেনে রাখা ভাল, এবং আমি প্যাটার্নটি পছন্দ করি। যাইহোক, এই সময়ে Promise.try , একটি পর্যায় 0 পরামর্শ তাই আপনি শুধুমাত্র একটি সঙ্গে এটি ব্যবহার করতে পারেন shim বা এই ধরনের Bluebird বা প্র: যেমন একটি প্রতিশ্রুতি গ্রন্থাগার ব্যবহার করে
Ori থেকে Drori

6
@ jfriend00 স্পষ্টতই এই সাধারণ উদাহরণে কোডটি অন্যভাবে আচরণ করবে না। কিন্তু যদি আপনার কোডটি rejectথাকে যা ব্যয়বহুল কিছু করে, যেমন ডাটাবেসগুলি বা এপিআই এর শেষ পয়েন্টগুলিতে সংযুক্ত হওয়ার মতো? এটি সমস্ত অপ্রয়োজনীয় হবে এবং আপনার অর্থ এবং সংস্থানগুলির জন্য ব্যয় হবে, বিশেষত যদি আপনি কোনও ডাব্লুএস ডাটাবেস বা এপিআই গেটওয়ে শেষ পয়েন্টের মতো কোনও সংযোগ করছেন। সেক্ষেত্রে অপ্রয়োজনীয় কোডটি কার্যকর করা থেকে বাঁচতে আপনি অবশ্যই একটি রিটার্ন ব্যবহার করবেন।
জেক উইলসন

3
@ জ্যাকউইলসন - অবশ্যই, এটি জাভাস্ক্রিপ্টে কেবলমাত্র সাধারণ কোড প্রবাহ এবং প্রতিশ্রুতির সাথে কিছু করার নেই। আপনি যদি ফাংশনটি প্রক্রিয়াকরণ শেষ করে থাকেন এবং বর্তমান কোডের পথে আর কোনও কোড কার্যকর করতে চান না, আপনি একটি sertোকান return
jender00

37

আপনার প্রচলিত চায়ের কাপ বা নাও হতে পারে এমন একটি প্রচলিত প্রবচনটি হ'ল সেই returnসাথে একত্রিত হওয়া reject, একই সাথে প্রতিশ্রুতি প্রত্যাখ্যান করা এবং ফাংশন থেকে প্রস্থান করা, যাতে ডাবলাসহ অন্যান্য ফাংশনটি resolveকার্যকর না হয়। আপনি যদি এই স্টাইলটি পছন্দ করেন তবে এটি আপনার কোডটিকে আরও কিছুটা কমপ্যাক্ট করে তুলতে পারে।

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {
    if (denominator === 0) return reject("Cannot divide by 0");
                           ^^^^^^^^^^^^^^
    resolve(numerator / denominator);
  });
}

এটি সূক্ষ্মভাবে কাজ করে কারণ প্রতিশ্রুতিবদ্ধ নির্মাণকারী কোনও রিটার্ন মান সহ কিছুই করে না এবং কোনও ক্ষেত্রে resolveএবং rejectকিছুই ফেরত দেয় না।

অন্য উত্তরে দেখানো কলব্যাক শৈলীর সাথে একই আইডিয়মটি ব্যবহার করা যেতে পারে:

function divide(nom, denom, cb){
  if(denom === 0) return cb(Error("Cannot divide by zero"));
                  ^^^^^^^^^
  cb(null, nom / denom);
} 

আবার, এটি সূক্ষ্মভাবে কাজ করে কারণ কলকারী ব্যক্তি divideএটি কিছু ফেরত প্রত্যাশা করে না এবং রিটার্ন মান সহ কিছু করে না।


6
আমি এটা পছন্দ করি না. এটি এমন ধারণা দেয় যে আপনি এমন কিছু ফিরিয়ে দিচ্ছেন যা আপনি বাস্তবে নন। আপনি প্রত্যাখাত ফাংশনটি অনুরোধ করছেন এবং তারপরে ফাংশনটির সম্পাদন শেষ করতে রিটার্নটি ব্যবহার করছেন। এগুলিকে আলাদা লাইনে রাখুন, আপনি যা করছেন তা কেবল মানুষকে বিভ্রান্ত করবে। কোড পঠনযোগ্যতা রাজা।
কে - এসও-তে বিষক্রিয়া বাড়ছে।

7
@ কার্লমরিসন আপনি আসলে প্রত্যাখ্যানিত প্রতিশ্রুতি "কিছু" ফিরিয়ে দিচ্ছেন। আমি মনে করি আপনি যে "ধারণা" সম্পর্কে কথা বলছেন তা খুব ব্যক্তিগত। কোনও rejectস্থিতি ফিরিয়ে দেওয়ার ক্ষেত্রে কোনও অসুবিধা নেই
ফ্রেন্ডর

5
@ ফ্রেন্ডর আমি মনে করি না আপনি কী লিখেছেন তা আপনি বুঝতে পেরেছেন। অবশ্যই আপনি এবং আমি এটি বুঝতে পারি, একই লাইনে রিজেক্ট প্রত্যাবর্তনের সময় কিছুই হয় না। কিন্তু এমন কোনও বিকাশকারীদের কী যা জাভাস্ক্রিপ্টে কোনও প্রকল্পে আসার অভ্যাস নয়? এই জাতীয় প্রোগ্রামিং এ জাতীয় লোকের পাঠযোগ্যতা হ্রাস করে। জাভাস্ক্রিপ্ট ইকো-সিস্টেম আজ যথেষ্ট জগাখিচুড়ি এবং এই ধরণের অনুশীলনগুলি ছড়িয়ে দেওয়া লোকেরা এটি আরও খারাপ করে দেবে। এটা খারাপ অভ্যাস।
কে - এসও-তে বিষক্রিয়া বাড়ছে।

1
@ কার্লমরিসন ব্যক্তিগত মতামত! = খারাপ অভ্যাস। এটি সম্ভবত একটি নতুন জাভাস্ক্রিপ্ট বিকাশকারীকে রিটার্নের সাথে কী চলছে তা বুঝতে সাহায্য করবে।
টবি Caulk

1
@ টবিকলক যদি লোকেরা কী শিখতে চায় যে কী রিটার্ন হয় তবে তাদের প্রতিশ্রুতি নিয়ে খেলতে হবে না, তাদের উচিত বেসিক প্রোগ্রামিং শেখা।
কে - এসও-তে বিষক্রিয়া বাড়ছে।

10

প্রযুক্তিগতভাবে এখানে 1 এর প্রয়োজন নেই - কারণ একটি প্রতিশ্রুতি সমাধান করা বা প্রত্যাখ্যান করা যেতে পারে , একচেটিয়াভাবে এবং কেবল একবার। প্রথম প্রতিশ্রুতি ফলাফল জিতে এবং পরবর্তী প্রতিটি ফলাফল উপেক্ষা করা হয়। এটি নোড-স্টাইলের কলব্যাক থেকে পৃথক

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

উপযুক্ত সময়ে ফিরে আসা (বা অন্যথায় "অন্যান্য" কেসটি কার্যকর না করার জন্য শর্তসাপেক্ষ ব্যবহার করে) কোনও অবৈধ অবস্থায় দুর্ঘটনাক্রমে কোড চালাওয়ার বা অযাচিত পার্শ্ব প্রতিক্রিয়া সম্পাদনের সম্ভাবনা হ্রাস করে; এবং এর ফলে কোডটি 'অপ্রত্যাশিতভাবে ব্রেকিং' এর প্রবণতা কম করে।


1 প্রযুক্তিগতভাবে এই উত্তরটিও এই বিষয়টির উপর নির্ভর করে যে এই ক্ষেত্রে "রিটার্ন" এর পরে কোডটি বাদ দেওয়া উচিত, ফলে কোনও পার্শ্ব-প্রতিক্রিয়া হবে না। জাভাস্ক্রিপ্ট আনন্দের সাথে শূন্য দ্বারা বিভক্ত হবে এবং হয় + ইনফিনিটি / -ইফিনিটি বা নাএন ফিরে আসবে।


সুন্দর পাদটীকা !!
হ্যাঙ্ককা

9

যদি আপনি কোনও সমাধান / প্রত্যাখ্যানের পরে "ফিরে" না যান, খারাপ জিনিস (যেমন কোনও পৃষ্ঠা পুনর্নির্দেশের মতো) বন্ধ হয়ে যাওয়ার বোঝার পরে ঘটতে পারে। সূত্র: আমি এই মধ্যে দৌড়ে।


6
উদাহরণস্বরূপ +1। আমার একটি সমস্যা ছিল যেখানে আমার প্রোগ্রামটি 100+ অবৈধ ডাটাবেস ক্যোয়ারী তৈরি করবে এবং এর কারণ আমি বুঝতে পারি না। দেখা যাচ্ছে আমি প্রত্যাখ্যান করার পরেও "ফিরতে" আসি না। এটি একটি ছোট ভুল তবে আমি আমার পাঠটি শিখেছি।
অ্যাডামইন দ্য অকুলাস

8

ওরির উত্তর ইতিমধ্যে ব্যাখ্যা করেছে যে এটি প্রয়োজনীয় নয় returnতবে এটি ভাল অনুশীলন is নোট করুন যে প্রতিশ্রুতিবদ্ধ নির্মাণকারী নিরাপদে ছুঁড়েছে তাই এটি পথে পরে পাস করা ছোঁড়া ব্যতিক্রম উপেক্ষা করবে, মূলত আপনার পার্শ্ব প্রতিক্রিয়া রয়েছে যা আপনি সহজেই পর্যবেক্ষণ করতে পারবেন না।

নোট করুন যে returnকলিগব্যাকগুলিতে প্রথম দিকে আইএনএন করা খুব সাধারণ:

function divide(nom, denom, cb){
     if(denom === 0){
         cb(Error("Cannot divide by zero");
         return; // unlike with promises, missing the return here is a mistake
     }
     cb(null, nom / denom); // this will divide by zero. Since it's a callback.
} 

সুতরাং, যখন এটি প্রতিশ্রুতিগুলিতে ভাল অনুশীলন হয় তখন এটি কলব্যাকগুলির সাথে প্রয়োজন । আপনার কোড সম্পর্কে কিছু নোট:

  • আপনার ব্যবহারের ঘটনাটি অনুমানমূলক, আসলে সিঙ্ক্রোনাস অ্যাকশন সহ প্রতিশ্রুতি ব্যবহার করবেন না।
  • প্রতিশ্রুতিবদ্ধ নির্মাণকারী ফেরতের মানগুলিকে উপেক্ষা করে । কিছু পাঠাগার সতর্ক করে দেবে যদি আপনি সেখানে ফিরে যাওয়ার ভুলের বিরুদ্ধে সতর্ক করতে কোনও অপরিজ্ঞাত মান ফিরে পান। বেশিরভাগই সেই চালাক নয়।
  • প্রতিশ্রুতিবদ্ধ নির্মাণকারী নিরাপদে নিক্ষেপ করা হয়েছে, এটি ব্যাতিক্রমকে অস্বীকারে রূপান্তরিত করবে তবে অন্যরা যেমন উল্লেখ করেছে - একটি প্রতিশ্রুতি একবারে সমাধান হয়ে যায়।

4

অনেক ক্ষেত্রে পৃথকভাবে প্যারামিটারগুলি বৈধতা দেওয়া এবং অবিলম্বে প্রতিশ্রুতি.রেজেক্ট (কারণ) দিয়ে প্রত্যাখ্যাত প্রতিশ্রুতি ফিরিয়ে দেওয়া সম্ভব ।

function divide2(numerator, denominator) {
  if (denominator === 0) {
    return Promise.reject("Cannot divide by 0");
  }
  
  return new Promise((resolve, reject) => {
    resolve(numerator / denominator);
  });
}


divide2(4, 0).then((result) => console.log(result), (error) => console.log(error));

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