2016-12-11 10 views
8

मैं वादे का वादा करने की कोशिश कर रहा हूं ताकि एक वादा खारिज कर दिया गया हो तो श्रृंखला टूट जाएगी। मैंने previous SO question की लीडों का पालन किया और इसे देशी वादों पर लागू करने की कोशिश की, लेकिन मुझे लगता है कि मैं काम करने के तरीके को गलत समझ रहा हूं।एक स्वच्छ तरीके से जावास्क्रिप्ट वादा श्रृंखला तोड़ें

Promise.resolve() 
    .then(function() { 
     return step(1) 
      .then(null, function() { 
       stepError(1); 
      }); 
    }) 
    .then(function() { 
     return step(2) 
      .then(null, function() { 
       stepError(2); 
      }); 
    }) 
    .then(function() { 
     return step(3) 
      .then(null, function() { 
       stepError(3); 
      }); 
    }); 

function step(n) { 
    console.log('Step '+n); 
    return (n === 2) ? Promise.reject(n) : Promise.resolve(n); 
} 

function stepError(n) { 
    console.log('Error '+n); 
    return Promise.reject(n); 
} 

ऊपर कोड के उत्पादन में है:

Step 1 
Step 2 
Error 2 
Step 3 
[UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): 2] 

मेरी समझ में, चरण 2 श्रृंखला तोड़ना चाहिए और चरण 3 नहीं करना चाहिए

यहाँ कैसे मैं कोड फिर से लिखा है सज़ा पाएं। जब चरण (2) एक अस्वीकृत वादा देता है, तो stepError (2) अपेक्षित के रूप में निष्पादित किया जाता है। लेकिन चूंकि यह Promise.reject (2) देता है, तो अगले में फ़ंक्शन निष्पादित नहीं किया जाना चाहिए, और चूंकि अंत में कोई पकड़ नहीं है, इसलिए चरण 2 के अस्वीकार किए गए वादे को लगता है - जैसा कि अपेक्षित है - इसे तब तक अग्रेषित किया जाना चाहिए जब तक यह निकल न जाए श्रृंखला क्योंकि इसे कोई हैंडलर नहीं मिला।

मुझे यहां क्या याद आ रही है? https://jsfiddle.net/6p4t9xyk/

उत्तर

10

मेरी समझ में, चरण 2 श्रृंखला तोड़ना चाहिए

यह होगा ..., लेकिन अगर आप गलती से परिवर्तित कर दिया है कि:

यहाँ एक JSFiddle साथ खेलने के लिए है एक संकल्प में अस्वीकृति।

वादों के बारे में महत्वपूर्ण बात यह है कि then के लिए हर कॉल एक नई वादा जो हल हो गई है बनाता है/पर क्या then कॉलबैक (रों) करते हैं, और कॉलबैक एक अस्वीकृति प्रसंस्करण आधारित अस्वीकार कर दिया धर्मान्तरित कि एक प्रस्ताव जब तक में अस्वीकृति यह जानबूझकर अन्यथा करता है।

तो यहाँ:

return step(2) 
    .then(null, function() { // This handler converts the 
     stepError(2);   // rejection into a resolution 
    });      // with the value `undefined` 

ताकि आप त्रुटि संचालकों कि त्रुटि के लिए क्षतिपूर्ति कर सकते हैं कि यही कारण है कि। बारी-बारी से,

return step(2) 
    .then(null, function() { 
     return stepError(2); // Added `return` 
    }); 

... या कि हैंडलर को पूरी तरह निकाल:

के बाद से stepError एक अस्वीकृति देता है, आप अस्वीकृति सिर्फ एक return जोड़कर जारी रख सकता

return step(2); 

... या आप कॉलबैक में throw कर सकते हैं, जो स्वचालित रूप से अस्वीकृति में बदल जाता है।

अनचाहे अस्वीकृति चेतावनी इस तथ्य के कारण होती है कि stepError से अस्वीकृति का कोई खपत नहीं होता है।

Promise.resolve() 
 
    .then(function() { 
 
     return step(1) 
 
      .then(null, function() { 
 
       return stepError(1); // Added `return` 
 
      }); 
 
    }) 
 
    .then(function() { 
 
     return step(2) 
 
      .then(null, function() { 
 
       return stepError(2); // Added `return` 
 
      }); 
 
    }) 
 
    .then(function() { 
 
     return step(3) 
 
      .then(null, function() { 
 
       return stepError(3); // Added `return` 
 
      }); 
 
    }); 
 

 
function step(n) { 
 
    console.log('Step '+n); 
 
    return (n === 2) ? Promise.reject(n) : Promise.resolve(n); 
 
} 
 

 
function stepError(n) { 
 
    console.log('Error '+n); 
 
    return Promise.reject(n); 
 
}

0

रूप @TJCrowder कहा, तुम return भूल त्रुटि हैंडलर का परिणाम (या से throw रहे हैं:


यहाँ stepError का परिणाम लौटने एक उदाहरण है यह)। इसे ठीक करने के लिए, मैं या तो

function withStepError(n, promise) { 
    return promise.catch(function(err) { 
     console.log('Error '+err+' from '+n); 
     throw new Error("failed at "+n); 
    }); 
} 
Promise.resolve() 
.then(function() { 
    return withStepError(1, step(1)); 
}) 
.then(function() { 
    return withStepError(2, step(2)); 
}) 
.then(function() { 
    return withStepError(3, step(3)); 
}); 

या

function getStepError(n) { 
    return function(err) { 
     console.log('Error '+err+' from '+n); 
     throw new Error("failed at "+n); 
    }; 
} 

Promise.resolve() 
.then(function() { 
    return step(1).catch(getStepError(1)); 
}) 
.then(function() { 
    return step(2).catch(getStepError(2)); 
}) 
.then(function() { 
    return step(3).catch(getStepError(3)); 
}); 
करने की सलाह देते चाहते हैं
संबंधित मुद्दे