【发布时间】:2017-04-29 00:12:31
【问题描述】:
我知道使用 Q 库很容易等待多个承诺完成,然后使用与这些承诺结果对应的值列表:
Q.all([
promise1,
promise2,
.
.
.
promiseN,
]).then(results) {
// results is a list of all the values from 1 to n
});
但是,如果我只对单一的、最快完成的结果感兴趣,会发生什么?举一个用例:假设我有兴趣检查大量文件,并且只要找到包含“津巴布韦”一词的任何文件,我就会满足。
我可以这样做:
Q.all(fileNames.map(function(fileName) {
return readFilePromise(fileName).then(function(fileContents) {
return fileContents.contains('zimbabwe') ? fileContents : null;
}));
})).then(function(results) {
var zimbabweFile = results.filter(function(r) { return r !== null; })[0];
});
但即使我已经找到“津巴布韦”,我也需要完成每个文件的处理。如果我有一个包含“zimbabwe”的 2kb 文件和一个不包含“zimbabwe”的 30tb 文件(假设我正在异步读取文件) - 那太愚蠢了!
我想要做的是在任何承诺得到满足的那一刻得到一个值:
Q.any(fileNames.map(function(fileName) {
return readFilePromise(fileName).then(function(fileContents) {
if (fileContents.contains('zimbabwe')) return fileContents;
/*
Indicate failure
-Return "null" or "undefined"?
-Throw error?
*/
}));
})).then(function(result) {
// Only one result!
var zimbabweFile = result;
}).fail(function() { /* no "zimbabwe" found */ });
使用这种方法,如果早期在我的 2kb 文件中发现“津巴布韦”,我将不会等待我的 30tb 文件。
但是没有Q.any这样的东西!
我的问题:如何获得这种行为?
重要提示:即使在其中一个内部承诺中发生错误,它也应该返回没有错误。
注意:我知道我可以通过在找到第一个有效值时抛出错误来破解 Q.all,但我更愿意避免这种情况。
注意:我知道类似Q.any 的行为可能是不正确的,或者在许多情况下是不恰当的。请相信我有一个有效的用例!
【问题讨论】:
-
不知道 Q 是否支持它,但原生承诺肯定支持。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
@KevinB 好点,已修复!我想混合 Q 和原生承诺不被认为是好的?你知道这方面的共识是什么吗?
-
@KevinB 在其他新闻中,实际上有
Q.race这样的东西 - 它没有记录,但它存在。如果您添加答案,我会给您支票! -
race方法在第一次拒绝时拒绝... -
@Hitmands 你说的是原生的
race方法吗?我将对Q中的那个做一些快速测试,看看它是否符合我的用例。
标签: node.js promise q cancellation