वादा श्रृंखला को तोड़ें और श्रृंखला में चरण के आधार पर एक फ़ंक्शन को कॉल करें जहां यह टूट गया है (अस्वीकृत)


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
यदि कोई और अधिक जटिल हो जाता है, तो एक async जावास्क्रिप्ट लिब की मदद हो सकती है
Lucuma

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) ), और इसी तरह से ।

यह स्पष्ट रूप से नहीं है कि तुम क्या इरादा है।

मान लें कि हम चाहते हैं कि कोई भी बात गलत न हो, इसके लिए संपूर्ण रिज़ॉल्यूशन श्रृंखला विफल होनी चाहिए:

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

नोट: हम इसे छोड़ सकते हैं handleErrorOneजहां यह है, क्योंकि यह केवल अगर आह्वान किया जाएगाstepOne अस्वीकार इसे अस्वीकार कर दिया जाएगा (यह श्रृंखला का पहला कार्य है, इसलिए हम जानते हैं कि यदि इस बिंदु पर श्रृंखला को अस्वीकार कर दिया गया है, तो यह केवल उस फ़ंक्शन के वादे के कारण हो सकता है) ।

महत्वपूर्ण परिवर्तन यह है कि अन्य कार्यों के लिए त्रुटि हैंडलर मुख्य वादा श्रृंखला का हिस्सा नहीं हैं। इसके बजाय, प्रत्येक चरण की अपनी "उप-श्रृंखला" होती हैonRejected जिसे केवल तभी कहा जाता है यदि चरण को अस्वीकार कर दिया गया था (लेकिन सीधे मुख्य श्रृंखला तक नहीं पहुंचा जा सकता है)।

कारण यह काम करता है कि दोनों onFulfilledऔर onRejectedके लिए वैकल्पिक तर्क हैं thenविधि। यदि एक वादा पूरा हुआ (यानी हल हो गया है) और thenश्रृंखला में अगले एक नहीं हैonFulfilled हैंडलर , तो श्रृंखला तब तक जारी रहेगी जब तक कि इस तरह के हैंडलर के साथ एक नहीं होता है।

इसका मतलब है कि निम्नलिखित दो पंक्तियाँ बराबर हैं:

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

लेकिन निम्नलिखित पंक्ति उपरोक्त दो के बराबर नहीं है:

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

$qएंगुलर का वादा पुस्तकालय क्रिस्क्वल की Qलाइब्रेरी पर आधारित है (जिसमें एक समृद्ध एपीआई है, लेकिन इसमें वह सब कुछ है जो आप पा सकते हैं $q)। GitHub पर Q का एपीआई डॉक्स उपयोगी साबित हो सकता है। क्यू वादे / ए + युक्ति को लागू करता है , जो विस्तार से बताता है कि कैसेthen और वादा संकल्प व्यवहार बिल्कुल काम करता है।

संपादित करें:

यह भी ध्यान रखें कि यदि आप अपने त्रुटि हैंडलर में श्रृंखला से बाहर निकलना चाहते हैं, तो उसे अस्वीकार किए गए वादे को वापस करना होगा या त्रुटि को फेंकना होगा (जो कि अस्वीकार किए गए वादे में स्वचालित रूप से पकड़ा और लपेटा जाएगा)। यदि आप एक वादा वापस नहीं करते हैं, तो आप के लिए thenएक संकल्प वादे में वापसी मूल्य लपेटता है।

इसका मतलब है कि यदि आप कुछ भी नहीं लौटाते हैं, तो आप प्रभावी रूप से मूल्य के लिए एक वादा किया हुआ वादा वापस कर रहे हैं undefined


138
इस भाग सोना है: if you don't return anything, you are effectively returning a resolved promise for the value undefined.धन्यवाद @pluma
वेलेरियो

7
यह वास्तव में है। मैं इसे संपादित करने के लिए बोल्ड के हकदार
हूं

वर्तमान फ़ंक्शन से बाहर निकलने को अस्वीकार करता है? उदाहरण के तौर पर अगर रिज़ॉल्यूशन को `` (बुरा) {रिजेक्ट (स्टेटस) कहा जाता है तो रिज़ॉल्यूशन नहीं कहा जाएगा; } संकल्प (परिणाम); `
SuperUberDuper 13

stepOne().then(stepTwo, handleErrorOne) `स्टेपऑन ()। फिर (अशक्त, हैंड्रेलऑन)। तब (स्टेप ट्व्वो)` क्या ये ट्रूली समान हैं? मुझे लगता है कि stepOneकोड की दूसरी पंक्ति में अस्वीकृति के मामले में निष्पादन होगा, stepTwoलेकिन पहले केवल निष्पादित handleErrorOneऔर बंद हो जाएगा। या क्या मैं कुछ न कुछ भूल रहा हूं?
जेफ 17

5
वास्तव में पूछे गए प्रश्न के लिए एक स्पष्ट समाधान प्रदान नहीं करता है, फिर भी अच्छी व्याख्या
यरकेन

57

पार्टी में थोड़ी देर हो गई लेकिन इस सरल समाधान ने मेरे लिए काम किया:

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

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

यह आपको करने की अनुमति देता तोड़ने श्रृंखला से बाहर।


1
मेरी मदद की, लेकिन FYI करें, आप इसे फिर से पकड़ में लाने के लिए वापस लौटा सकते हैं जैसे:.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
बस स्पष्ट करने के लिए, यदि कोई त्रुटि stepOne () में होती है, तो दोनों चेनइयर को सही से लागू किया जाता है? अगर यह वांछनीय है। मेरे पास एक स्निपेट है, जो यह सुनिश्चित नहीं करता है कि अगर मुझे कुछ गलत समझ में आया
runkit.com/embed/9q2q3rjxdar9

10

आपको जिस चीज की आवश्यकता है, वह दोहराई जा रही है .then() श्रृंखला, जिसे शुरू करने के लिए एक विशेष मामले और समाप्त करने के लिए एक विशेष मामला है।

अंतिम विफलता हैंडलर के माध्यम से रिपल करने के लिए विफलता मामले की चरण संख्या प्राप्त करने के लिए knack है।

  • प्रारंभ करें: कॉल करें 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
m59, यह पूछे गए प्रश्न का उत्तर है, "मैं वादे कैसे लिखूं ताकि मैं अस्वीकृति पर एक फ़ंक्शन को कॉल कर सकूं, त्रुटि श्रृंखला के सभी कार्यों को कॉल किए बिना?" और प्रश्न का शीर्षक, "वादा तोड़ो श्रृंखला और श्रृंखला में चरण के आधार पर एक फ़ंक्शन को कॉल करें जहां यह टूट गया है (अस्वीकृत)"
चुकंदर-चुकंदर

जैसा कि मैंने कहा, यह जानकारीपूर्ण है और मैंने इस समाधान को अपनी पोस्ट में भी शामिल किया है (कम विवरण के साथ)। यह दृष्टिकोण चीजों को ठीक करने के लिए है ताकि श्रृंखला जारी रह सके। हालांकि यह पूरा कर सकता है कि मैं क्या देख रहा हूं, यह स्वाभाविक नहीं है जितना कि स्वीकृत उत्तर में दृष्टिकोण। दूसरे शब्दों में, यदि आप वही करना चाहते हैं जो शीर्षक द्वारा व्यक्त किया गया है और जो प्रश्न पूछा गया है, तो आघात का दृष्टिकोण अपनाएं।
m59

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()पहले चरण की विफलता के मामले में वापस आकर, आप उस वादे को अस्वीकार कर रहे हैं, जिसके कारण त्रुटि कॉलबैक 2 में कहा जाता है then(...)


दुनिया में क्या ... यही मैंने किया है! मेरे पोस्ट में देखें कि मैंने ऐसा करने की कोशिश की, लेकिन श्रृंखला वापस अंदर और दौड़ जाएगी step(2)। अब मैंने बस कोशिश की फिर ऐसा नहीं हो रहा है। मैं बहुत उलझन में हूँ।
m59

1
मैंने देखा कि आपने इसका उल्लेख किया है। हालांकि यह विचित्र है। उस फ़ंक्शन को जिसमें return step(2);केवल तभी बुलाया जाना चाहिए जब step(1)सफलतापूर्वक हल हो।
जाजन

स्क्रैच कि - यह निश्चित रूप से हो रहा है। जैसे मैंने अपनी पोस्ट में कहा था, यदि आप उपयोग नहीं करते हैं return $q.reject(), तो श्रृंखला जारी रहेगी । इस मामले में return responseइसे गड़बड़ कर दिया। इसे देखें: jsbin.com/EpaZIsIp/6/edit
m59

अच्छा ठीक है। यह आपके द्वारा पोस्ट किए गए jsbin में काम करने के लिए प्रकट होता है जब मैंने उसे बदल दिया था, लेकिन मुझे कुछ याद नहीं होगा।
जाजन

हाँ, मैं निश्चित रूप से देखता हूं कि अब काम नहीं कर रहा हूं। मेरे लिए ड्राइंग बोर्ड पर वापस!
जाजन

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)तो मुझे चेतावनी मिल रही है कि वादा एक गैर-वस्तु के साथ खारिज कर दिया
9me


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() बहुत उपयोगी नीचे।

(स्वीकृत उत्तर का उल्लेख है 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

सबसे अच्छा समाधान ईएस 6 प्रतीक्षा का उपयोग करने के लिए अपने वादे की श्रृंखला के लिए रिफ्लेक्टर है। तब आप केवल फ़ंक्शन से शेष व्यवहार को छोड़ने के लिए वापस आ सकते हैं।

मैं एक साल से अधिक समय से इस पैटर्न के खिलाफ सिर हिला रहा हूं और प्रतीक्षा का स्वर्ग का उपयोग कर रहा हूं।


शुद्ध IE का उपयोग करते समय async / प्रतीक्षा का समर्थन नहीं किया जाता है।
ndee

0

एक SequentialPromise मॉड्यूल का उपयोग करें

इरादा

एक मॉड्यूल प्रदान करें जिसकी जिम्मेदारी क्रमबद्ध तरीके से अनुरोधों को निष्पादित करना है, जबकि प्रत्येक ऑपरेशन के वर्तमान सूचकांक को क्रमबद्ध तरीके से ट्रैक करना है। लचीलेपन के लिए एक कमांड पैटर्न में ऑपरेशन को परिभाषित करें ।

प्रतिभागियों

  • प्रसंग : वह वस्तु जिसका सदस्य विधि एक ऑपरेशन करता है।
  • SequentialPromise : executeप्रत्येक ऑपरेशन को चेन और ट्रैक करने के लिए एक विधि को परिभाषित करता है । SequentialPromise प्रदर्शन किए गए सभी ऑपरेशनों से एक वादा-श्रृंखला देता है।
  • Invoker : एक SequentialPromise उदाहरण बनाता है, इसे संदर्भ और कार्रवाई प्रदान करता है, और executeप्रत्येक ऑपरेशन के लिए विकल्पों की एक क्रमिक सूची में गुजरते समय इसकी विधि कहता है ।

परिणाम

जब प्रॉमिस रिज़ॉल्यूशन के ऑर्डिनल बिहेवियर की ज़रूरत हो तो सीक्वेंशियल प्राइज़ का इस्तेमाल करें। SequentialPromise उस सूचकांक को ट्रैक करेगा जिसके लिए एक वादा खारिज कर दिया गया था।

कार्यान्वयन

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);
  });

यदि पहला वादा कोई परिणाम नहीं देता है तो आपको केवल कंसोल में 'कोई परिणाम नहीं' मिलेगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.