当前位置: 首页 > 面试题库 >

在promisifyAll创建的then链中使用cancel()

鞠安民
2023-03-14
问题内容

不知道我对这个标题是否足够清楚,但是假设我有一个名为Foo的类method1method2并且带有method3。我承诺使用的方法promisifyAll

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

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

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

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方法中,但这将对我的真实代码造成很大的变化。


问题答案:

尝试这样的事情:

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取消执行fun2和fun3的唯一方法是抛出异常。与promise类似,一个then处理程序可以取消执行下一个处理程序的唯一方法then是返回被拒绝的promise。就像使用同步代码一样,抛出的异常将被该catch块捕获,在这里被拒绝的Promise将被传递给catch处理程序。

使用同步代码,您可以拥有一个内部机制try/catch来捕获异常,如果该异常不是您用来取消执行的特定异常,则将其重新引发。使用promise,您可以拥有一个更早的catch处理程序,该处理程序实际上是相同的。

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



 类似资料:
  • 整个系统的第一条链是由开发团队创建,创建过程和其他区块链系统一样。 其他的链都是通过“创链交易”创建的。 每条链允许创建2条子链,只要条件满足,任何人都可以创建。 第二条和第三条链的创建没有限制,任何人随时可以创建。 后续链的创建,需要满足以下几个条件: 链的平均区块大于300K(近期平均值),避免无限制创建。 需要花费代币,代币量最大为区块奖励的一万倍,平均交易量越大,花费越低。 子链不存在才能

  • 我试图在OpenAPI 3.0规范中创建一个响应链接。更具体地说,我想提供我的一个响应和其他可用操作之间的已知关系(参见。链接对象)。 在我的SpringBoot项目中,我使用Springdoc(版本:1.3.9)生成API文档。根据@ApiResponse#links文档,我已尝试使用以下endpoint代码实现我的目标: 不幸的是,我看不到任何结果在招摇过市的用户界面,但“没有链接”的描述。

  • 问题内容: 我有一个日志文件,其中使用python记录了一些测试命令及其状态(通过/失败)。现在,我希望测试命令不应写为简单文本,而应写为超链接。这样,当我单击它们时,将打开另一个链接到它们的文件。 例如: 现在,我希望写在logfile.log中的CommandName应该是文件TestCommand.log的超链接,以便当我单击CommandName时,文件TestCommand.log会打开

  • 问题内容: 我有一个标题字符串和一个链接字符串。我不确定如何将两者放在一起以使用Javascript在页面上创建链接。任何帮助表示赞赏。 编辑1:向该问题添加更多详细信息。我试图找出原因的原因是因为我有一个RSS提要,并且有标题和URL的列表。我想将标题链接到URL以使页面有用。 EDIT2:我使用的是jQuery,但它是全新的,并且不知道它可以在这种情况下提供帮助。 问题答案:

  • 基本上我知道我必须创建两个类,一个名为“链表”的类代表整个列表,一个名为“节点”的类代表列表的每个元素,但我完全迷路了,我甚至不知道如何在不同的节点中“保存”每个元素,我以前从未使用过动态数据结构。如有任何帮助,不胜感激

  • 问题内容: 有没有一种方法可以在Markdown中创建在新窗口中打开的链接?如果没有,建议您使用哪种语法。我将其添加到我使用的markdown编译器中。我认为这应该是一个选择。 问题答案: 就Markdown语法而言,如果要详细说明,则只需使用HTML。 我见过的大多数Markdown引擎都允许使用纯旧的HTML,仅在这种情况下,即通用文本标记系统无法将其截断。(例如,StackOverflow引