[英]How to break a promise chain?
I'm aware that there are similar questions, but I haven't seen any that address this chaining pattern.
我知道也有类似的问题,但是我还没有看到任何解决此链接模式的问题。
I have the following: 我有以下几点:
var runTests = function (chain, resolutionTest) {
return chain.then(function (result) {
if (result)
return result; // Early return if the previous tests were successful. This is where I want to prevent other attempts.
const attempt = tryOpenStream(resolutionTest).then(streamToDom);
return attempt;
});
}
// from someplace else
numTests = resolutionTests.length;
return resolutionTests.reduce(runTests, Promise.resolve()); // start reduce with an empty promise
The problem that I'm encountering is that I'm calling tryOpenStream
many times even after I've captured a result
. 我遇到的问题是即使我捕获了
result
后,我也多次调用tryOpenStream
。
Options I'm considering: 我正在考虑的选项:
throw new Error(result)
instead of return result
. throw new Error(result)
而不是return result
。 This would break the chain (I think...) but it's misusing Error
and would be easily misunderstood by another developer. Error
,并且很容易被其他开发人员误解。 How can I break this chain at return result;
如何在
return result;
打破此链return result;
? ?
UPDATE 1 更新1
I'm trying the following: 我正在尝试以下方法:
var makeTest = function (runMoreTests, resolutionTest) {
return function runTest() {
return tryOpenStream(resolutionTest).then(streamToDom).then(function (result) {
if (result)
return result;
else
return runMoreTests();
});
};
}
return resolutionTestBuilder.buildTests().then(function (resolutionTests) {
numTests = resolutionTests.length;
return resolutionTests.reduceRight(makeTest, function () { Promise.reject("No resolutions succeeded.") })();
});
However no calls to runTest
are invoked. 但是,不会调用
runTest
的任何调用。 This is a bit of new syntax for me so I'll research some and update with any findings. 这对我来说是个新语法,因此我将进行一些研究并根据发现进行更新。
UPDATE 2 更新2
I was missing the ()
to invoke the reduceRight
. 我缺少
()
来调用reduceRight
。 Though now I'm seeing that reject
called even with success... though when I step through, that rejection isn't invoked. 尽管现在我看到即使成功也
reject
调用...尽管当我逐步执行时,不会调用该拒绝。 It's as if by the time I get a result back, all links in the chain have been invoked. 好像到我返回结果时一样,链中的所有链接都已被调用。
Try using this: 尝试使用此:
function runTests(resolutionTest) {
return tryOpenStream(resolutionTest).then(streamToDom)
}
// from someplace else
function loop(tests, i) {
if (i === tests.length) return undefined
return runTests(tests[i]).then(function (result) {
if (result) return result
return loop(tests, i + 1)
})
}
return loop(resolutionTests, 0)
Although I do wonder why you can't use an exception to denote your tryOpenStream
failed. 尽管我确实想知道为什么您不能使用异常来表示
tryOpenStream
失败。 That would actually simplify your code some. 这实际上可以简化您的代码。
Both flags and exceptions can be used, but as you noticed they're not the proper tool. 标志和异常都可以使用,但是正如您注意到的那样,它们不是正确的工具。
Instead, use recursion, like in @IsiahMeadows' answer, or a right fold: 相反,请使用递归(例如@IsiahMeadows的答案)或右折叠:
var makeTest = function (runMoreTests, resolutionTest) {
return function runTest(result) {
if (result)
return result;
return tryOpenStream(resolutionTest).then(streamToDom).then(runMoreTests);
};
}
return Promise.resolve(resolutionTests.reduceRight(makeTest, x => x)(undefined));
or better written as 或更好地写为
var makeTest = function (runMoreTests, resolutionTest) {
return function runTest() {
return tryOpenStream(resolutionTest).then(streamToDom).then(result => {
if (result)
return result;
else
return runMoreTests();
});
};
}
return resolutionTests.reduceRight(makeTest, () => Promise.reject("nothing succeeded"))();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.