我知道有类似的问题,但我还没有看到任何解决这种链接模式的问题。
我有以下内容:
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
我遇到的问题是,即使在我抓住了tryOpenStream
之后,我也多次拨打result
。
我考虑的选项:
throw new Error(result)
代替return result
。这会破坏链条(我认为......),但它会误导Error
并且很容易被其他开发者误解。如何在return result;
打破此链?
更新1
我正在尝试以下方法:
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.") })();
});
但是没有调用runTest
的调用。这对我来说是一种新的语法,所以我会研究一些并更新任何发现。
更新2
我错过了()
来调用reduceRight
。虽然现在我看到reject
甚至成功地调用了......但是当我单步执行时,不会调用该拒绝。它好像在我得到结果时,链中的所有链接都已被调用。
答案 0 :(得分:1)
尝试使用:
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)
虽然我很想知道为什么你不能使用例外来表示你的tryOpenStream
失败了。这实际上会简化你的代码。
答案 1 :(得分:1)
可以使用标志和例外,但正如您所注意到的那样,它们不是正确的工具。
相反,使用递归,就像@ IsiahMeadows'回答,或右折:
SELECT tblRoster.EDIPI, [tblRoster].[LastName] & ", " & [tblRoster].[FirstName] & " " & Left$([tblRoster].[MiddleName],1) AS [Full Name], tblBasicIndividualRecords.PriMilOccSpec AS MOS, DLookUp("LongName","tblMilitaryOccupationalSpecialties","tblMilitaryOccupationalSpecialties!ID = " & [tblBasicIndividualRecords].[PriMilOccSpec]) AS [MOS Decription], DLookUp("Abbreviation","tblRankStructure","tblRankStructure!ID = " & [tblRoster].[Rank]) AS Rank, Format([EndOfActiveService],"yymmdd") AS EAS, tblBasicIndividualRecords.Billet, tblBasicIndividualRecords.OnHand, tblBasicIndividualRecords.Remarks, tblBasicIndividualRecords.Deployable, tblRankStructure.SortValue, tblMilitaryOccupationalSpecialties.SortOrder
FROM tblMilitaryOccupationalSpecialties INNER JOIN ((tblRankStructure INNER JOIN tblRoster ON tblRankStructure.ID = tblRoster.Rank) INNER JOIN tblBasicIndividualRecords ON tblRoster.EDIPI = tblBasicIndividualRecords.EDIPI) ON (tblMilitaryOccupationalSpecialties.ID = tblBasicIndividualRecords.AddMilOccSpec.Value) AND (tblMilitaryOccupationalSpecialties.ID = tblBasicIndividualRecords.PriMilOccSpec)
ORDER BY tblRankStructure.SortValue DESC;
或更好地写为
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));