প্রতিশ্রুতি শৃঙ্খলা ভঙ্গ করুন এবং সেই শৃঙ্খলে যেখানে পদক্ষেপ রয়েছে সেখানে পদক্ষেপের ভিত্তিতে একটি ফাংশন কল করুন (প্রত্যাখ্যাত)


135

হালনাগাদ:

এই পোস্টের ভবিষ্যতের দর্শকদের সহায়তা করতে, আমি প্লুমার উত্তরটির এই ডেমোটি তৈরি করেছি

প্রশ্ন:

আমার লক্ষ্যটি মোটামুটি সোজা মনে হচ্ছে।

  step(1)
  .then(function() {
    return step(2);
  }, function() {
    stepError(1);
    return $q.reject();
  })
  .then(function() {

  }, function() {
    stepError(2);
  });

  function step(n) {
    var deferred = $q.defer();
    //fail on step 1
    (n === 1) ? deferred.reject() : deferred.resolve();
    return deferred.promise;
  }
  function stepError(n) {
    console.log(n); 
  }

এখানে সমস্যাটি হ'ল আমি যদি পদক্ষেপ 1 এ ব্যর্থ হই তবে stepError(1)এবং উভয়ই stepError(2)বরখাস্ত করা হয়। আমি যদি তা না করি return $q.rejectতবে stepError(2)বরখাস্ত করা হবে না, তবে step(2)হবে, যা আমি বুঝতে পারি। আমি যা করার চেষ্টা করছি তা বাদ দিয়ে আমি সবকিছু সম্পাদন করেছি।

আমি প্রতিশ্রুতিগুলি কীভাবে লিখব যাতে আমি ত্রুটি শৃঙ্খলে সমস্ত ফাংশন কল না করে প্রত্যাখ্যানের কোনও ফাংশন কল করতে পারি? বা এটি সম্পাদন করার অন্য কোনও উপায় আছে?

এখানে একটি লাইভ ডেমো রয়েছে যাতে আপনার সাথে কিছু কাজ হয়ে যায়।

হালনাগাদ:

আমি এক ধরনের সমাধান করেছি। এখানে আমি চেইনের শেষে ত্রুটিটি ধরছি এবং ডেটাটি reject(data)এমনভাবে প্রেরণ করছি যাতে আমি ত্রুটি ফাংশনটিতে কী সমস্যাটি পরিচালনা করতে হবে তা জানতে পারি। এটি আসলে আমার প্রয়োজনীয়তাগুলি পূরণ করে না কারণ আমি ডেটার উপর নির্ভর করতে চাই না। এটি লম্পট হবে, তবে আমার ক্ষেত্রে ফাংশনটিতে ত্রুটি কলব্যাক পাস করার চেয়ে কী হবে তা নির্ধারণের জন্য ফিরিয়ে দেওয়া ডেটার উপর নির্ভর করার চেয়ে ক্লিনার হবে।

এখানে লাইভ ডেমো (ক্লিক করুন)।

step(1)
  .then(function() {
    return step(2);
  })
  .then(function() {
    return step(3);
  })
  .then(false, 
    function(x) {
      stepError(x);
    }
  );
  function step(n) {
    console.log('Step '+n);
    var deferred = $q.defer();
    (n === 1) ? deferred.reject(n) : deferred.resolve(n);
    return deferred.promise;
  }
  function stepError(n) {
    console.log('Error '+n); 
  }

1
এখানে একটি অ্যাসিঙ্ক জাভাস্ক্রিপ্ট লিব রয়েছে যা এটি আরও জটিল হয়ে উঠলে সহায়তা করতে পারে
লুচুমা

Promise.prototype.catch()এমডিএন-তে উদাহরণগুলি একই সমস্যার জন্য সমাধান দেখায়।
toraritte

উত্তর:


199

আপনার কোডটি প্রত্যাশিতভাবে কাজ না করার কারণ হ'ল এটি আসলে আপনার যা ভাবেন তার থেকে আলাদা কিছু করে চলেছে।

আসুন আমরা আপনার নীচের মত কিছু আছে বলুন:

stepOne()
.then(stepTwo, handleErrorOne)
.then(stepThree, handleErrorTwo)
.then(null, handleErrorThree);

কী ঘটছে তা আরও ভালভাবে বুঝতে, আসুন এটির জন্য try/ catchব্লক সহ সিঙ্ক্রোনাস কোড :

try {
    try {
        try {
            var a = stepOne();
        } catch(e1) {
            a = handleErrorOne(e1);
        }
        var b = stepTwo(a);
    } catch(e2) {
        b = handleErrorTwo(e2);
    }
    var c = stepThree(b);
} catch(e3) {
    c = handleErrorThree(e3);
}

onRejectedহ্যান্ডলার (এর দ্বিতীয় যুক্তি then) মূলত একটি ত্রুটি সংশোধন প্রক্রিয়া (ক মত হল catchব্লক)। যদি কোনও ত্রুটি নিক্ষেপ handleErrorOneকরা হয় তবে এটি পরবর্তী ক্যাপ ব্লক ( catch(e2)) ইত্যাদি দ্বারা ধরা পড়বে ।

এটি আপনার উদ্দেশ্য হিসাবে স্পষ্টতই নয়।

আসুন আমরা বলি যে আমরা যাই হোক না কেন পুরো রেজোলিউশন শৃঙ্খলাটি ব্যর্থ হোক to

stepOne()
.then(function(a) {
    return stepTwo(a).then(null, handleErrorTwo);
}, handleErrorOne)
.then(function(b) {
    return stepThree(b).then(null, handleErrorThree);
});

দ্রষ্টব্য: এটি handleErrorOneযেখানে রয়েছে সেখানেই আমরা এটি ছেড়ে দিতে পারি, কারণ এটি কেবল তখন stepOneপ্রত্যাখ্যান করা হবে যদি তা প্রত্যাখ্যান করা হয় (এটি চেইনের প্রথম কাজ, তাই আমরা জানি যে এই চেইনটি যদি প্রত্যাখ্যান করা হয় তবে এটি কেবল সেই ফাংশনের প্রতিশ্রুতির কারণেই হতে পারে) ।

গুরুত্বপূর্ণ পরিবর্তনটি হ'ল অন্যান্য ফাংশনগুলির জন্য ত্রুটি পরিচালনাকারীরা মূল প্রতিশ্রুতির শৃঙ্খলার অংশ নয়। পরিবর্তে, প্রতিটি পদক্ষেপের একটি নিজস্ব "সাব-চেইন" থাকে onRejectedযা কেবল তখনই বলা হয় যদি পদক্ষেপটি প্রত্যাখ্যান করা হয়েছিল (তবে সরাসরি মূল চেইনে পৌঁছানো যায় না)।

এই কাজ করার কারণটি হ'ল উভয়ই onFulfilledএবং পদ্ধতিতে onRejectedoptionচ্ছিক যুক্তি then। যদি কোনও প্রতিশ্রুতি পূর্ণ হয় (যেমন সমাধান করা) এবং thenচেইনের পরবর্তীটিতে কোনও onFulfilledহ্যান্ডলার না থাকে তবে এই ধরণের হ্যান্ডলারের সাথে উপস্থিত না হওয়া অবধি চেইন অব্যাহত থাকবে।

এর অর্থ নিম্নলিখিত দুটি লাইন সমান:

stepOne().then(stepTwo, handleErrorOne)
stepOne().then(null, handleErrorOne).then(stepTwo)

তবে নিম্নলিখিত রেখাটি উপরের দুটিটির সমতুল্য নয় :

stepOne().then(stepTwo).then(null, handleErrorOne)

$qঅ্যাঙ্গুলারের প্রতিশ্রুতি গ্রন্থাগারটি ক্রিস্কোয়াল Qলাইব্রেরির উপর ভিত্তি করে (যার আরও সমৃদ্ধ এপিআই রয়েছে, তবে আপনি খুঁজে পেতে পারেন এমন সমস্ত কিছু রয়েছে $q)। গিটহাবের কিউ এর এপিআই ডক্স দরকারী প্রমাণ করতে পারে। কিউ প্রতিশ্রুতিগুলি / এ + স্পিক প্রয়োগ করে , যা thenপ্রতিশ্রুতি সমাধানের আচরণটি ঠিক কীভাবে কাজ করে সে সম্পর্কে বিস্তারিতভাবে যায় ।

সম্পাদনা করুন:

এছাড়াও মনে রাখবেন যে আপনি যদি নিজের ত্রুটি হ্যান্ডলারের শৃঙ্খলটি ভেঙে ফেলতে চান তবে এটি একটি প্রত্যাখ্যাত প্রতিশ্রুতি ফিরিয়ে দিতে বা একটি ত্রুটি নিক্ষেপ করতে হবে (যা ধরা পড়ে এবং স্বয়ংক্রিয়ভাবে প্রত্যাখ্যাত প্রতিশ্রুতিতে আবৃত হয়ে যায়)। যদি আপনি কোন প্রতিশ্রুতি ফেরত না পান তবে আপনার জন্য একটি প্রতিশ্রুতিতে thenরিটার্নের মানটি মোড়ানো।

এর অর্থ হ'ল আপনি যদি কিছু ফিরিয়ে না দেন তবে আপনি কার্যকরভাবে মানটির জন্য একটি সমাধান প্রতিশ্রুতি ফিরিয়ে দিচ্ছেন undefined


138
এই ভাগে সোনা হল: if you don't return anything, you are effectively returning a resolved promise for the value undefined.ধন্যবাদ @pluma
Valerio

7
এটা আসলে। আমি এটির জন্য উপযুক্ত সাহসী হিসাবে এটি সম্পাদনা করছি
সাইরিল CHAPON

বর্তমান ফাংশন প্রস্থান প্রত্যাখ্যান করে? যেমন প্রত্যাখাতকে 1 ম `যদি (খারাপ) {প্রত্যাখ্যান (স্থিতি) বলা হয় তবে সংকল্প ডাকা হবে না; } সমাধান (ফলাফল); `
সুপারউবারডুপার

stepOne().then(stepTwo, handleErrorOne) `স্টেপওন ()। তারপরে (নাল, হ্যান্ডেল এররওন) then তারপর (পদক্ষেপ দুটি) these এগুলি কি ট্রুলি সমতুল্য? আমি মনে করি stepOneকোডের দ্বিতীয় লাইনে প্রত্যাখ্যানের ক্ষেত্রে কার্যকর হবে stepTwoতবে প্রথমটি কেবল কার্যকর হবে handleErrorOneএবং থামবে। নাকি আমি কিছু মিস করছি?
JeFf

5
তথাপি জিজ্ঞাসিত প্রশ্নের সুস্পষ্ট সমাধান সরবরাহ করে না, তবুও ভাল ব্যাখ্যা
যেরকেন

57

পার্টিতে দেরিতে হলেও এই সহজ সমাধানটি আমার পক্ষে কাজ করেছে:

function chainError(err) {
  return Promise.reject(err)
};

stepOne()
.then(stepTwo, chainError)
.then(stepThreee, chainError);

এটি আপনাকে শৃঙ্খল থেকে বেরিয়ে আসতে দেয় ।


1
আমাকে কিন্তু এফওয়াইআইকে সাহায্য করেছে, আপনি তখনই এটি ফিরিয়ে দিতে পারেন ক্যাচের মতো ছিটকে যাওয়ার জন্য:.then(user => { if (user) return Promise.reject('The email address already exists.') })
ক্রেগ ভ্যান টন্ডার

1
@ ক্রেইগওয়ানটেন্ডার আপনি কেবল একটি প্রতিশ্রুতির মধ্যে ফেলে দিতে পারেন এবং এটি আপনার কোডের মতোই কাজ করবে:.then(user => { if (user) throw 'The email address already exists.' })
ফ্রান্সিসকো প্রেজেন্সিয়া

1
এটিই একমাত্র সঠিক উত্তর। অন্যথায় 3 ধাপে এখনও কার্যকর করা হবে এমনকি পদক্ষেপ 1 এ ত্রুটি রয়েছে।
wdetac

1
কেবল স্পষ্ট করে বলতে গেলে, যদি কোনও ত্রুটি স্টেপওনে () এ ঘটে থাকে, তবে উভয় শৃঙ্খলাভুতই ঠিক অনুরোধ করে? যদি এই পছন্দসই। আমার একটি স্নিপেট রয়েছে যা এটি করে, আমি কিছু ভুল বুঝেছি
9

10

আপনার যা দরকার তা হ'ল একটি পুনরাবৃত্তি .then()চেইন যা শুরু করার জন্য একটি বিশেষ কেস এবং একটি বিশেষ কেস সমাপ্ত।

চূড়ান্ত ব্যর্থতার কেসটির চূড়ান্ত নম্বরটি চূড়ান্ত ত্রুটি হ্যান্ডলারের কাছে পৌঁছানো The

  • শুরু করুন: step(1)নিঃশর্ত কল করুন ।
  • পুনরাবৃত্তি প্যাটার্ন: .then()নিম্নলিখিত কলব্যাকগুলির সাথে চেইন করুন :
    • সাফল্য: কল পদক্ষেপ (এন + 1)
    • ব্যর্থতা: পূর্ববর্তী ডিফেন্ডারকে প্রত্যাখ্যান করা বা ত্রুটিটির পুনর্বিবেচনা দেওয়া মানটি নিক্ষেপ করুন।
  • সমাপ্তি: .then()সাফল্যের কোনও হ্যান্ডলার এবং একটি চূড়ান্ত ত্রুটি হ্যান্ডলার সহ চেইন এ ।

আপনি পুরো জিনিসটি লম্বাটে লিখতে পারেন তবে নামকরণ, সাধারণীকৃত ফাংশন সহ ধরণটি প্রদর্শন করা আরও সহজ:

function nextStep(n) {
    return step(n + 1);
}

function step(n) {
    console.log('step ' + n);
    var deferred = $q.defer();
    (n === 3) ? deferred.reject(n) : deferred.resolve(n);
    return deferred.promise;
}

function stepError(n) {
    throw(n);
}

function finalError(n) {
    console.log('finalError ' + n);
}
step(1)
    .then(nextStep, stepError)
    .then(nextStep, stepError)
    .then(nextStep, stepError)
    .then(nextStep, stepError)
    .then(nextStep, stepError)
    .then(null, finalError);});

দেখতে ডেমো

কীভাবে কীভাবে step()স্থগিত করা হয়েছে তা দ্রবীভূত করা হয়েছে বা এর সাথে সমাধান করা হয়েছে তা নোট করুন n, এভাবে পরবর্তী সময়ে কলব্যাকগুলিতে সেই মানটি উপলব্ধ করা হবে .then()। একবার stepErrorবলা হয়ে গেলে , ত্রুটিটি বার বার পুনরায় পুনরারম্ভ করা হয় যতক্ষণ না এটি পরিচালনা করা হয় finalError


তথ্যবহুল উত্তর যাতে এটি রাখা মূল্যবান তবে আমি যে সমস্যার মুখোমুখি হচ্ছি তা নয়। আমি আমার পোস্টে এই সমাধানটি উল্লেখ করেছি এবং এটি আমি যা খুঁজছি তা নয়। আমার পোস্টের শীর্ষে ডেমোটি দেখুন।
m59

1
এম 59, এটি জিজ্ঞাসা করা প্রশ্নের একটি উত্তর, "আমি কীভাবে প্রতিশ্রুতিগুলি লিখব যাতে আমি ত্রুটি শৃঙ্খলে সমস্ত ক্রিয়াকলাপটি কল না করে প্রত্যাখ্যানের কোনও ফাংশন বলতে পারি?" এবং প্রশ্নের শিরোনাম, "প্রতিশ্রুতি শৃঙ্খলা ভঙ্গ করুন এবং সেই শৃঙ্খলে যেখানে ভাঙা হয়েছে সেখানে পদক্ষেপের ভিত্তিতে একটি ফাংশন কল করুন (প্রত্যাখ্যাত)"
বিট্রুট-বিটরুট

ঠিক আছে, যেমনটি আমি বলেছিলাম, এটি তথ্যপূর্ণ এবং আমি এমনকি এই পোস্টটি আমার পোস্টে অন্তর্ভুক্ত করেছি (কম বিশদ সহ)। এই পদ্ধতির বিষয়গুলি স্থির করার উদ্দেশ্যে করা হয়েছে যাতে চেইনটি চালিয়ে যেতে পারে। যদিও আমি যা খুঁজছি তা এটি সম্পাদন করতে পারে , তবে এটি গৃহীত উত্তরের পদ্ধতির মতো স্বাভাবিক নয়। অন্য কথায়, আপনি যদি শিরোনাম এবং জিজ্ঞাসিত প্রশ্ন দ্বারা প্রকাশিত যা করতে চান তবে প্লুমার পদ্ধতির নিন।
এম59

7

প্রত্যাখ্যান করার সময় আপনাকে একটি প্রত্যাখ্যান ত্রুটিটি পাস করা উচিত, তারপরে কোনও ক্রিয়াকলাপে পদক্ষেপ ত্রুটি হ্যান্ডলারগুলি মোড়ানো হবে যা পরীক্ষা করে প্রত্যাখ্যানটি প্রক্রিয়া করা উচিত বা "পুনর্বিবেচনা" হওয়া উচিত কিনা তা শৃঙ্খলা শেষ না হওয়া পর্যন্ত:

// function mocking steps
function step(i) {
    i++;
    console.log('step', i);
    return q.resolve(i);
}

// function mocking a failing step
function failingStep(i) {
    i++;
    console.log('step '+ i + ' (will fail)');
    var e = new Error('Failed on step ' + i);
    e.step = i;
    return q.reject(e);
}

// error handler
function handleError(e){
    if (error.breakChain) {
        // handleError has already been called on this error
        // (see code bellow)
        log('errorHandler: skip handling');
        return q.reject(error);
    }
    // firs time this error is past to the handler
    console.error('errorHandler: caught error ' + error.message);
    // process the error 
    // ...
    //
    error.breakChain = true;
    return q.reject(error);
}

// run the steps, will fail on step 4
// and not run step 5 and 6
// note that handleError of step 5 will be called
// but since we use that error.breakChain boolean
// no processing will happen and the error will
// continue through the rejection path until done(,)

  step(0) // 1
  .catch(handleError)
  .then(step) // 2
  .catch(handleError)
  .then(step) // 3
  .catch(handleError)
  .then(failingStep)  // 4 fail
  .catch(handleError)
  .then(step) // 5
  .catch(handleError)
  .then(step) // 6
  .catch(handleError)
  .done(function(){
      log('success arguments', arguments);
  }, function (error) {
      log('Done, chain broke at step ' + error.step);
  });

আপনি কনসোলে কী দেখতে পাবেন:

step 1
step 2
step 3
step 4 (will fail)
errorHandler: caught error 'Failed on step 4'
errorHandler: skip handling
errorHandler: skip handling
Done, chain broke at step 4

এখানে কিছু কার্যকরী কোড https://jsfiddle.net/8hzg5s7m/3/

যদি আপনার প্রতিটি পদক্ষেপের জন্য নির্দিষ্ট হ্যান্ডলিং থাকে তবে আপনার মোড়কের এমন কিছু হতে পারে:

/*
 * simple wrapper to check if rejection
 * has already been handled
 * @param function real error handler
 */
function createHandler(realHandler) {
    return function(error) {
        if (error.breakChain) {
            return q.reject(error);
        }
        realHandler(error);
        error.breakChain = true;
        return q.reject(error);    
    }
}

তারপরে আপনার চেইন

step1()
.catch(createHandler(handleError1Fn))
.then(step2)
.catch(createHandler(handleError2Fn))
.then(step3)
.catch(createHandler(handleError3Fn))
.done(function(){
    log('success');
}, function (error) {
    log('Done, chain broke at step ' + error.step);
});

2

যদি আমি সঠিকভাবে বুঝতে পারি, আপনি ব্যর্থ পদক্ষেপটি প্রদর্শন করতে কেবল ত্রুটি চান, তাই না?

এটি প্রথম প্রতিশ্রুতির ব্যর্থতার ক্ষেত্রে পরিবর্তন করার মতোই সহজ হওয়া উচিত:

step(1).then(function (response) {
    step(2);
}, function (response) {
    stepError(1);
    return response;
}).then( ... )

$q.reject()প্রথম পদক্ষেপের ব্যর্থতার ক্ষেত্রে ফিরে এসে আপনি সেই প্রতিশ্রুতিটি প্রত্যাখ্যান করছেন, যার ফলে ত্রুটি কলব্যাককে ২ য় কল করতে ডাকা হয় then(...)


পৃথিবীতে কি ... আমি ঠিক তাই করেছি! আমার পোস্টে দেখুন যে আমি এটি চেষ্টা করেছিলাম, তবে চেইনটি আবার শুরু হবে এবং চালাবে step(2)। এখন আমি আবার চেষ্টা করেছিলাম এটি ঘটছে না। আমি খুবই দ্বিধাগ্রস্ত.
এম59

1
আমি দেখেছি আপনি যে উল্লেখ করেছেন। যদিও উদ্ভট। সেই ফাংশনটিতে return step(2);কেবল তখনই কল করা উচিত যখন step(1)সফলভাবে সমাধান হয়।
জাজন

স্ক্র্যাচ যে - এটি অবশ্যই ঘটছে। আমি আমার পোস্টে যেমন বলেছি, আপনি যদি ব্যবহার না করেন return $q.reject()তবে চেইনটি চলতে থাকবে। এই ক্ষেত্রে return responseএটি বিশৃঙ্খলার সৃষ্টি। এটি দেখুন: jsbin.com/EpaZIsIp/6/edit
m59

হুম ঠিক আছে. এটি পোস্ট করা জেসবিনে এটি প্রকাশিত হয়েছিল যখন আমি এটি পরিবর্তন করেছি তবে আমি অবশ্যই কিছু মিস করেছি।
জাজন

হ্যাঁ আমি অবশ্যই দেখতে পাচ্ছি যে এখন কাজ করছে না। আমার জন্য অঙ্কন বোর্ডে ফিরে!
জাজন

2
var s = 1;
start()
.then(function(){
    return step(s++);
})
.then(function() {
    return step(s++);
})
.then(function() {
    return step(s++);
})
.then(0, function(e){
   console.log(s-1); 
});

http://jsbin.com/EpaZIsIp/20/edit

অথবা যে কোনও পদক্ষেপের জন্য স্বয়ংক্রিয়ভাবে:

var promise = start();
var s = 1;
var l = 3;
while(l--) {
    promise = promise.then(function() {
        return step(s++);
    });
}
promise.then(0, function(e){
   console.log(s-1); 
});

http://jsbin.com/EpaZIsIp/21/edit


তবে আমি যদি কল deferred.reject(n)দিই তবে আমি সতর্কতা পাচ্ছি যে প্রতিশ্রুতি একটি নন-ইরর অবজেক্ট


2

আপনি যদি async / অপেক্ষা করে এই সমস্যাটি সমাধান করতে চান:

(async function(){    
    try {        
        const response1, response2, response3
        response1 = await promise1()

        if(response1){
            response2 = await promise2()
        }
        if(response2){
            response3 = await promise3()
        }
        return [response1, response2, response3]
    } catch (error) {
        return []
    }

})()

1

পদক্ষেপগুলি কার্যকর করতে সরাসরি চেইনের উপাদান হিসাবে ত্রুটি হ্যান্ডলার সংযুক্ত করুন:

        // Handle errors for step(1)
step(1).then(null, function() { stepError(1); return $q.reject(); })
.then(function() {
                 // Attach error handler for step(2),
                 // but only if step(2) is actually executed
  return step(2).then(null, function() { stepError(2); return $q.reject(); });
})
.then(function() {
                 // Attach error handler for step(3),
                 // but only if step(3) is actually executed
  return step(3).then(null, function() { stepError(3); return $q.reject(); });
});

বা ব্যবহার catch():

       // Handle errors for step(1)
step(1).catch(function() { stepError(1); return $q.reject(); })
.then(function() {
                 // Attach error handler for step(2),
                 // but only if step(2) is actually executed
  return step(2).catch(function() { stepError(2); return $q.reject(); });
})
.then(function() {
                 // Attach error handler for step(3),
                 // but only if step(3) is actually executed
  return step(3).catch(function() { stepError(3); return $q.reject(); });
});

দ্রষ্টব্য: এটি মূলত তার উত্তরে প্লুমার পরামর্শ অনুসারে একই প্যাটার্ন কিন্তু ওপি'র নাম ব্যবহার করে।


1

পাওয়া Promise.prototype.catch()MDN তে উদাহরণ খুব সহায়ক থেকে কম।

(গৃহীত উত্তরে উল্লেখ করা হয় then(null, onErrorHandler)যা মূলত একই রকম catch(onErrorHandler)))

ক্যাচ পদ্ধতিটি ব্যবহার করে এবং শৃঙ্খলাবদ্ধ

var p1 = new Promise(function(resolve, reject) {
  resolve('Success');
});

p1.then(function(value) {
  console.log(value); // "Success!"
  throw 'oh, no!';
}).catch(function(e) {
  console.log(e); // "oh, no!"
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});

// The following behaves the same as above
p1.then(function(value) {
  console.log(value); // "Success!"
  return Promise.reject('oh, no!');
}).catch(function(e) {
  console.log(e); // "oh, no!"
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});

ত্রুটি নিক্ষেপ করার সময় গটচস

// Throwing an error will call the catch method most of the time
var p1 = new Promise(function(resolve, reject) {
  throw 'Uh-oh!';
});

p1.catch(function(e) {
  console.log(e); // "Uh-oh!"
});

// Errors thrown inside asynchronous functions will act like uncaught errors
var p2 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    throw 'Uncaught Exception!';
  }, 1000);
});

p2.catch(function(e) {
  console.log(e); // This is never called
});

// Errors thrown after resolve is called will be silenced
var p3 = new Promise(function(resolve, reject) {
  resolve();
  throw 'Silenced Exception!';
});

p3.catch(function(e) {
   console.log(e); // This is never called
});

যদি সমাধান হয়

//Create a promise which would not call onReject
var p1 = Promise.resolve("calling next");

var p2 = p1.catch(function (reason) {
    //This is never called
    console.log("catch p1!");
    console.log(reason);
});

p2.then(function (value) {
    console.log("next promise's onFulfilled"); /* next promise's onFulfilled */
    console.log(value); /* calling next */
}, function (reason) {
    console.log("next promise's onRejected");
    console.log(reason);
});

1

সেরা সমাধান হ'ল আপনার প্রতিশ্রুতি শৃঙ্খলে রিফেক্টর ES6 অপেক্ষার জন্য ব্যবহার করুন। তারপরে আপনি বাকী ব্যবহারটি এড়াতে কেবল ফাংশন থেকে ফিরে আসতে পারেন।

আমি এক বছরেরও বেশি সময় ধরে এই প্যাটার্নটির বিরুদ্ধে মাথা ঘুরিয়ে আসছি এবং অপেক্ষার স্বর্গ ব্যবহার করছি।


খাঁটি IE async ব্যবহার করার সময় / অপেক্ষার সমর্থন নেই।
14

0

সিকোয়েনশিয়ালপ্রাইম মডিউলটি ব্যবহার করুন

উদ্দেশ্য

একটি মডিউল সরবরাহ করুন যার দায়িত্ব যথাযথভাবে অনুরোধগুলি কার্যকর করা, যখন প্রতিটি ক্রিয়াকলাপের বর্তমান সূচকে একটি সাধারণ পদ্ধতিতে ট্র্যাক করে। কমান্ড প্যাটার্নে অপারেশনটি সংজ্ঞায়িত করুননমনীয়তার জন্য ।

অংশগ্রহণকারীরা

  • প্রসঙ্গ : যে সদস্য পদ্ধতিটি একটি ক্রিয়া সম্পাদন করে।
  • সিকোয়েনশিয়াল প্রমাইজ : executeপ্রতিটি ক্রিয়াকলাপ শৃঙ্খলাবদ্ধ এবং ট্র্যাক করতে একটি পদ্ধতি নির্ধারণ করে। সিকোয়েনশিয়ালপ্রোমিস সম্পাদিত সমস্ত ক্রিয়াকলাপ থেকে একটি প্রতিশ্রুতি-চেইন প্রদান করে।
  • ইনভোকার : এটিকে প্রসঙ্গ এবং ক্রিয়া সরবরাহ করে একটি সিক্যুয়ালপ্রোমাইজ উদাহরণ তৈরি করে executeএবং প্রতিটি ক্রিয়াকলাপের জন্য বিকল্পগুলির একটি সাধারণ তালিকায় যাওয়ার সময় এর পদ্ধতিটি কল করে ।

ফল

প্রতিশ্রুতি সমাধানের সাধারণ আচরণ প্রয়োজন হলে সিকোয়েনশিয়ালপ্রাইম ব্যবহার করুন। সিকোয়েনশিয়াল প্রমাইজ সেই সূচিটি ট্র্যাক করবে যার জন্য একটি প্রতিশ্রুতি প্রত্যাখ্যান করা হয়েছিল।

বাস্তবায়ন

clear();

var http = {
    get(url) {
        var delay = Math.floor( Math.random() * 10 ), even = !(delay % 2);
        var xhr = new Promise(exe);

        console.log(`REQUEST`, url, delay);
        xhr.then( (data) => console.log(`SUCCESS: `, data) ).catch( (data) => console.log(`FAILURE: `, data) );

        function exe(resolve, reject) {
            var action = { 'true': reject, 'false': resolve }[ even ];
            setTimeout( () => action({ url, delay }), (1000 * delay) );
        }

        return xhr;
    }
};

var SequentialPromise = new (function SequentialPromise() {
    var PRIVATE = this;

    return class SequentialPromise {

        constructor(context, action) {
            this.index = 0;
            this.requests = [ ];
            this.context = context;
            this.action = action;

            return this;
        }

        log() {}

        execute(url, ...more) {
            var { context, action, requests } = this;
            var chain = context[action](url);

            requests.push(chain);
            chain.then( (data) => this.index += 1 );

            if (more.length) return chain.then( () => this.execute(...more) );
            return chain;
        }

    };
})();

var sequence = new SequentialPromise(http, 'get');
var urls = [
    'url/name/space/0',
    'url/name/space/1',
    'url/name/space/2',
    'url/name/space/3',
    'url/name/space/4',
    'url/name/space/5',
    'url/name/space/6',
    'url/name/space/7',
    'url/name/space/8',
    'url/name/space/9'
];
var chain = sequence.execute(...urls);
var promises = sequence.requests;

chain.catch( () => console.warn(`EXECUTION STOPPED at ${sequence.index} for ${urls[sequence.index]}`) );

// console.log('>', chain, promises);

সারকথা

SequentialPromise


0

যদি কোনও মুহুর্তে আপনি ফিরে Promise.reject('something')যান তবে আপনাকে প্রতিশ্রুতিতে ক্যাচ ব্লকে ফেলে দেওয়া হবে।

promiseOne
  .then((result) => {
    if (!result) {
      return Promise.reject('No result');
    }
    return;
  })
  .catch((err) => {
    console.log(err);
  });

যদি প্রথম প্রতিশ্রুতি কোনও ফলাফল না ফেরায় তবে আপনি কেবল কনসোলে 'ফলাফল নয়' পেয়ে যাবেন ।

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