gpt4 book ai didi

node.js - 在 promisifyAll 创建的 then 链中使用 cancel()

转载 作者:太空宇宙 更新时间:2023-11-04 00:32:16 25 4
gpt4 key购买 nike

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

然后我有一个 then 链,我想取消第二个或第一个 then 中间的操作,并且不应调用进一步的 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';

结果是一样的,但你不想抛出错误,所以你可以返回一个被拒绝的 promise 。

更新 1

但是,如果您的目的是连续运行所有 3 个方法,那么您还需要在每一步返回下一个 promise ,如下所示:

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 block 捕获一样,这里被拒绝的 Promise 将被传递给 catch 处理程序。

使用同步代码,您可以拥有一个内部 try/catch 来捕获异常,如果它不是您用于取消执行的特定异常,则重新抛出该异常。通过 Promise,您可以拥有一个早期的 catch 处理程序,其功能基本相同。

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

关于node.js - 在 promisifyAll 创建的 then 链中使用 cancel(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40515775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com