Learning promises and exceptions vs. rejecting in Q

霸气de小男生 提交于 2019-12-07 22:22:19

问题


I'm under the impression that an exception inside a promise will trigger the subsequent fail-handler, but I'm not seeing it happen in this code:

var Q = require('q');

function x() {
  console.log('x');
  var deferred = Q.defer();

  setTimeout(
      function() {
        console.log('resolving x');
        deferred.resolve('hi');
      },
      1000
  );

  return deferred.promise;
}

function y() {
  console.log('y');
  var deferred = Q.defer();

  setTimeout(
      function() {
        console.log('throwing in y');
        throw new Error('Oih!');
      },
      1000
  );

  return deferred.promise;
}

x().then(y).then(
    function () {
      console.log('yes');
    },
    function () {
      console.log('no');
    }
);

Am I doing something wrong, or have I misunderstood?


回答1:


You are mixing callbacks and promises + you have a case of deferred anti-pattern. Either use Q.delay or a wrapper like:

function delay(ms) {
    var d = Q.defer();
    setTimeout(d.resolve, ms);
    return d.promise;
}

Now that there is promise API for timeouts, there is no reason to use setTimeout:

function x() {
    return delay(1000).then(function () {
        console.log("hi");
    });
}

function y() {
    return delay(1000).then(function () {
        console.log('throwing in y');
        throw new Error('Oih!');
    });
}

Use:

x()
.then(y)
.then(function() {
    console.log('yes');
})
.catch(function(e) {
     console.log('no');
});



回答2:


All exceptions inside a promise chain are catched. You must either manage a failing promise as you did, or end the promise chain using done() in order to expose and throw the error (see the documentation).

However, the error you're throwing in the setTimeout is not related to the promise as the error is thrown asynchronously, see for instance this relevant question. The alternative is to reject the promise like this:

function y() {
  console.log('y');
  var deferred = Q.defer();

  setTimeout(
      function() {
        console.log('throwing in y');
        deferred.reject(new Error('Oih!'));
      },
      1000
  );

  return deferred.promise;
}


来源:https://stackoverflow.com/questions/20041737/learning-promises-and-exceptions-vs-rejecting-in-q

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!