在promisifyAll创建的then链中使用cancel() [英] Use cancel() inside a then-chain created by promisifyAll

查看:87
本文介绍了在promisifyAll创建的then链中使用cancel()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不确定我是否对这个标题足够清楚,但是假设我有一个名为Foo的类,其中包含method1method2method3.我用promisifyAll来表示其方法.

Not sure if I'm clear enough with this title, but assume that I have a class called Foo with method1, method2 and method3. I promisify its methods with promisifyAll.

然后我有一个then链,我想在第二个或第一个中途取消操作,然后再不调用它.

Then I have a then-chain and I want to cancel the operation in the middle of the second or first then, and no further then should be called.

我阅读了有关取消的信息( http://bluebirdjs.com/docs/api/cancellation. html ),但我不知道如何使用promisifyAll来实现它.

I read about Cancellation (http://bluebirdjs.com/docs/api/cancellation.html) but I don't know how to implement it with promisifyAll.

我得到的代码加上我需要的东西:

The code I got plus what I need:

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

获得此结果的正确方法是什么? 我知道我可以扔一些东西并用catch方法捕获它,但这将对我的真实代码造成很大的改变.

What is the proper way of having this result? I know I can just throw something and catch it in the catch method, but this would make a very big change in my real code.

推荐答案

尝试如下操作:

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';

结果将是相同的,但是您不想抛出错误,因此您可以返回被拒绝的诺言.

and the result would be the same but you didn't want to throw errors so you can return a rejected promise instead.

但是,如果您打算连续运行所有3个方法,那么您还需要在每个步骤中返回下一个承诺,如下所示:

But if your intention is to run all 3 methods in series then you will also need to return the next promise at each step with something like this:

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

当前,您问题中的代码将永远不会运行除第一个方法以外的任何其他方法.

Currently the code in your question would never run any other method than the first one.

在这种情况下,另一个不调用最后一个catch的示例:

Another example that doesn't call the last catch for that case:

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

说明

这样想:如果有的话,在同步代码中

Explanation

Think of it this way: in synchronous code if you had:

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

然后,fun1取消执行fun2和fun3的唯一方法是引发异常.与promise类似,一个then处理程序可以取消执行下一个then处理程序的唯一方法是返回被拒绝的promise.就像使用同步代码一样,抛出异常的事件将被catch块捕获,在这里被拒绝的承诺将被传递给catch处理程序.

then the only way for fun1 to cancel the execution of fun2 and fun3 would be to throw an exception. And similarly for promises, the only way that one then handler could cancel the execution of the next then handler is to return a rejected promise. And just like with synchronous code that thrown exception would be caught by the catch block, here that rejected promise would be passed to the catch handler.

使用同步代码,您可以拥有一个内部try/catch,该内部try/catch可以捕获异常,如果不是您用来取消执行的特定异常,则将其抛出.有了promises,您可以拥有一个更早的catch处理程序,该处理程序实际上是相同的.

With synchronous code you can have an internal try/catch that catches the exception and rethrows it if it isn't the specific one that you used to cancel your execution. With promises you can have an earlier catch handler that does essentially the same.

这是Update 2中的代码发生的情况.拒绝原因与某个值(在该示例中为'some reason')进行比较,如果相等,则返回已解决的Promise,因此下一个catch处理程序未调用.如果不相等,则拒绝原因再次返回,作为拒绝的诺言女巫,然后作为您希望最后一个catch处理程序处理的真实"错误传递给下一个catch处理程序.

This is what happens with the code in Update 2. The rejection reason is compared to some value (which is 'some reason' in that example) and if it is equal then a resolved promise is returned and so the next catch handler is not called. If it is not equal then the rejection reason is returned again as a rejected promise witch is then passed to the next catch handler as a "real" error that you want that last catch handler to handle.

这篇关于在promisifyAll创建的then链中使用cancel()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆