node.js - का उपयोग करें() को फिर से-चेन के द्वारा प्रकाशित करें



promise bluebird (1)

इस तरह से कुछ प्रयास करें:

var bluebird = require('bluebird');

function Foo() { }

Foo.prototype.method1 = function (cb) { cb(null, 'method1'); };
Foo.prototype.method2 = function (cb) { cb(null, 'method2'); };
Foo.prototype.method3 = function (cb) { cb(null, 'method3'); };

var foo = bluebird.promisifyAll(new Foo());

foo.method1Async()
.then(function (r1) {
  console.log('step 1');
  // cancel then-chain
  console.log("Task stopped");
  // just stop right here
  return bluebird.reject('some reason');
})
.then(function (r2) {
  console.log('step 2');
  console.log(r2);
}).then(function (r3) {
  console.log('step 3');
  console.log(r3);
})
.catch(function (er) {
  console.log('Catch!');
  console.log('Error:', er);
});

के बजाय:

  return bluebird.reject('some reason');

आप उपयोग कर सकते हैं:

  throw 'some reason';

और परिणाम समान होगा, लेकिन आप त्रुटियों को नहीं फेंकना चाहते थे ताकि आप बदले में अस्वीकृत वादे वापस कर सकें।

अपडेट 1

लेकिन अगर आपका इरादा श्रृंखला में सभी 3 तरीकों को चलाने के लिए है तो आपको प्रत्येक चरण में अगले वादे को इस तरह से वापस करना होगा:

var bluebird = require('bluebird');

function Foo() { }

Foo.prototype.method1 = function (cb) { cb(null, 'method1'); };
Foo.prototype.method2 = function (cb) { cb(null, 'method2'); };
Foo.prototype.method3 = function (cb) { cb(null, 'method3'); };

var foo = bluebird.promisifyAll(new Foo());

foo.method1Async()
.then(function (r1) {
  console.log('step 1');
  console.log('got value:', r1);
  // cancel? change to true:
  var cancel = false;
  if (cancel) {
    console.log("Task stopped");
    return bluebird.reject('some reason');
  } else {
    console.log('Keep going');
    return foo.method2Async();
  }
})
.then(function (r2) {
  console.log('step 2');
  console.log('got value:', r2);
  return foo.method3Async();
}).then(function (r3) {
  console.log('step 3');
  console.log('got value:', r3);
})
.catch(function (er) {
  console.log('Catch!');
  console.log('Error:', er);
});

वर्तमान में आपके प्रश्न में कोड कभी भी पहले किसी की तुलना में कोई अन्य विधि नहीं चलाएगा

अपडेट 2

एक और उदाहरण जो कि उस केस के अंतिम catch को नहीं बुलाता है:

foo.method1Async()
.then(function (r1) {
  console.log('step 1');
  console.log('got value:', r1);
  // cancel? change to true:
  var cancel = true;
  if (cancel) {
    console.log("Task stopped");
    return bluebird.reject('some reason');
  } else {
    console.log('Keep going');
    return foo.method2Async();
  }
})
.then(function (r2) {
  console.log('step 2');
  console.log('got value:', r2);
  return foo.method3Async();
}).then(function (r3) {
  console.log('step 3');
  console.log('got value:', r3);
})
.catch(function (er) {
  if (er === 'some reason') {
    return bluebird.resolve('ok');
  } else {
    return bluebird.reject(er);
  }
})
.catch(function (er) {
  console.log('Catch!');
  console.log('Error:', er);
});

व्याख्या

इसके बारे में सोचें: तुल्यकालिक कोड में यदि आपके पास था:

r1 = fun1();
r2 = fun2();
r3 = fun3();

तो fun1 और fun3 के निष्पादन को रद्द करने के लिए fun1 के लिए एकमात्र तरीका अपवाद फेंकना होगा। और इसी तरह वादों के लिए, एकमात्र तरीका है कि एक then हेन्डलर अगले के निष्पादन को रद्द कर सकता है then हेन्डलर अस्वीकार किए गए वादे को वापस करना है और बस सिंक्रोनस कोड के साथ जिस तरह से अपवाद फेंका गया हो, catch ब्लॉक से पकड़ा जाएगा, यहाँ कि catch हैंडलर को अस्वीकार कर दिया गया वादा पारित किया जाएगा।

सिंक्रोनस कोड के साथ आप एक आंतरिक try/catch कर सकते हैं जो अपवाद फैलाता है और इसे पुनः निर्दिष्ट करता है यदि यह विशिष्ट नहीं है जो आपने अपने निष्पादन को रद्द करने के लिए उपयोग किया था। वादे के साथ आप एक पहले catch हैंडल रख सकते हैं जो अनिवार्यतः एक ही है।

यह अपडेट 2 में कोड के साथ होता है। अस्वीकृति का कारण कुछ मान (जो उस उदाहरण में 'some reason' ) से तुलना की जाती है और यदि यह बराबर है तो एक हलया वादा वापस किया जाता है और इसलिए अगले catch हैंडलर को नहीं कहा जाता है । यदि यह बराबर नहीं है तो अस्वीकार का कारण फिर से लौटा दिया जाता है क्योंकि अस्वीकार किए गए वायदे के चुड़ैल को अगले catch हैंडलर को "वास्तविक" त्रुटि के रूप में भेजा जाता है, जिसे आप चाहते हैं कि आखिरी catch हैंडलर को संभालना

निश्चित नहीं कि मैं इस शीर्षक के साथ पर्याप्त स्पष्ट हूं, लेकिन मान लें कि मेरे पास method2 , method2 और method3 साथ फू नामक एक वर्ग है। मैं इसके तरीकों के promisifyAll साथ promisifyAll

उसके बाद मेरे पास एक श्रृंखला है और मैं दूसरे या पहले के बीच में ऑपरेशन को रद्द करना चाहता हूं, और आगे नहीं कहा जाना चाहिए।

मैंने रद्दीकरण ( http://bluebirdjs.com/docs/api/cancellation.html ) के बारे में पढ़ा है, लेकिन मुझे यह नहीं पता कि इसे कैसे लागू करना है, सब कुछ बताओ।

मुझे जो कोड की जरूरत है, उसके साथ मैं क्या चाहता हूं:

var bluebird = require('bluebird');

function Foo() { }

Foo.prototype.method1 = function (cb) {};

Foo.prototype.method2 = function (cb) {};

Foo.prototype.method3 = function (cb) {};

var foo = bluebird.promisifyAll(new Foo());

foo.method1Async()
.then(function (r1) {
  // cancel then-chain
  res.json("Task stopped");
  // just stop right here
  promises.cancel();
})
.then(function (r2) {
  console.log(r2);
}).then(function (r3) {
  console.log(r3);
})
.catch(function (er) {
  console.log('Catch!');
});

यह परिणाम होने का सही तरीका क्या है? मुझे पता है कि मैं सिर्फ कुछ को फेंक कर पकड़ कर पकड़ कर सकता हूं, लेकिन यह मेरे असली कोड में बहुत बड़ा परिवर्तन कर देगा।





bluebird