我对不同的API(由delayedPromise函数模拟)执行多个请求,每个请求都需要一定的时间才能完成。如果其中一个满足,我返回它解析的值,就这样。我现在一个接一个地做这些,因为第一个请求是最准确的,而第二个则不太准确,等等。因此,如果第一个请求失败,第二个满足,我将返回第二个请求
为了加快速度,我考虑将这些请求并行化。为了实现这一点,我正在创建一个数组,它持有promise,它等待第一个元素的结果,如果失败,它等待第二个元素的结果等...
这是代码:
function promiseTest() {
return new Promise(function (resolve, reject) {
let promises = []
new Promise(async function (resolve, reject) {
promises.push(delayedPromise(true, 10000, "1")) //If true resolves after 10000 ms; false = reject
promises.push(delayedPromise(false, 1000, "2"))
promises.push(delayedPromise(false, 1000, "3"))
let answer;
let answer2
let answer3;
answer = await promises[0].catch(async err => {
answer2 = await promises[1].catch(async err => {
answer3 = await promises[2].catch(err => { reject(err) })
})
})
if (answer != undefined) {
resolve(answer)
}
else if (answer2 != undefined) {
resolve(answer2)
}
else if (answer3 != undefined) {
resolve(answer3)
}
}).then(res => resolve(res)).catch(err => {reject(err)})
})
}
function delayedPromise(bool, time,string ="") {
return new Promise(function (resolve, reject) {
if (bool) {
setTimeout(resolve(string), time)
}
else {
setTimeout(reject(), time)
}
})
}
问题是,虽然这种方法有效
答:很可能不是最好的解决方案,也很难扩展
B:上面的代码创建了一堆未捕获的异常错误。我相信这是当我收到答案1的结果时,我不会处理其他函数返回的任何拒绝。
有没有更好的方法来解决上述问题?如果有任何想法或改进,我将不胜感激!非常感谢
附言:如果你能更好地表达我的标题,请让我知道我正在努力用一句话来表达我的问题
我认为,在仍然并行运行promise的同时(为了获得最佳的端到端时间),对结果进行加权以支持promise需要构建一个特殊的循环。我想你可以这样做:
const errResult = Symbol('errResult');
// fns is an array of functions to call
// args is a array of arguments to pass to each function (same args to each)
async function getResult(fns, args) {
// start all the async operations to run in parallel
const promises = fns.map(fn => {
// Rejections will resolve with a sentinel value so we can detect them
// This helps us avoid ever getting an unhandled rejection error
// on promises that reject after we've already found our desired value
return fn(...args).catch(err => {
return errResult;
});
});
// now await them in order so you can find the first
// one that completes (in order)
// Promises that rejected have been converted into an errResult
// resolve to help in avoiding unhandled rejections
// after we return with our good first result
for (let p of promises) {
let result = await p;
if (result !== errResult) {
return result;
}
}
throw new Error('no results');
}
// sample usage:
getResult([fn1, fn2, fn3, fn4], [argA,argB]).then(result => {
console.log(result);
}).catch(err => {
console.log("no results found");
});
如果您希望每个函数都有不同的参数,那么只需将其构建到fn1、fn2等中...这样他们就可以用所需的参数调用根函数,然后让args数组成为一个空数组。
问题中的代码简化为:
function promiseTest() {
let promises = [
delayedPromise(true, 10000, '1'),
delayedPromise(false, 1000, '2'),
delayedPromise(false, 1000, '3')
];
return promises[0]
.catch(() => promises[1])
.catch(() => promises[2]);
}
一旦遇到成功的promise,链将停止捕获,成功的结果将一路下降,以传递(proverd-wrp)给promise测试的调用方。
捕获链也可以写如下。。。
Promise.reject()
.catch(() => promises[0])
.catch(() => promises[1])
.catch(() => promises[2]);
... 这有助于为任意长度的数组制定过程化版本,如下所示:
function promiseTest() {
let promises = [...]; // array of Promises (any length)
return promises.reduce((p_, p) => p_.catch(() => p), Promise.reject());
}
假设在制定promise
数组时没有采取措施避免未经处理的拒绝,您可以在减少中这样做(使用一系列“分支捕获”)。。。
function promiseTest() {
let promises = [...]; // array of Promises (any length).
return promises.reduce((p_, p) => {
p.catch(() => null); // avoid unhandled rejections.
return p_.catch(() => p);
}, Promise.reject());
}
Promise.any
和Promise.all解决
非常相似,但并不完全符合您的要求。你必须自己建造它。这就是我要做的:
async function first(iterable) {
const promises = [];
for (const thenable of iterable) {
const promise = Promise.resolve(thenable);
promises.push(promise);
promise.catch(() => {}); // ignore rejections, we'll handle them later
}
const errors = [];
for (const promise of promises) {
try {
return await promise;
} catch(error) {
errors.push(error);
}
}
throw new AggregateError(errors);
}
考虑以下以串行/顺序方式读取文件数组的代码。返回一个promise,该promise仅在按顺序读取所有文件后才解析。 上面的代码可以工作,但我不喜欢必须为事情按顺序发生而做递归。有没有更简单的方法可以重写这段代码,使我不必使用我怪异的函数? 最初,我尝试使用,但这导致所有调用并发发生,这不是我想要的:
本文向大家介绍Java程序来填充int数组中的元素,包括了Java程序来填充int数组中的元素的使用技巧和注意事项,需要的朋友参考一下 可以使用java.util.Arrays.fill()方法将元素填充到int数组中。此方法将所需的int值分配给Java中的int数组。所需的两个参数是数组名称和要存储在数组元素中的值。 演示此的程序如下所示- 示例 输出结果 现在让我们了解上面的程序。 首先定义
将oneArr 按照 twoArr 的顺序进行排序,而且两个数组可能一样长,也可能不一样长, twoArr 是基于oneArr选中的数据,oneArr 是接口返回的数据,
我这里的问题是,获取promise在当前文本之前创建了几个字符,然后在最后创建的promise之后解析。我需要解决的最后一个promise的最新或取消以前的promise时,我改变了文本。 我希望结果总是最新的。 我查找了一些搜索栏示例,但什么也没找到。 我很确定解决方案是保存以前的promise,如果在你创建一个新promise时它仍然悬而未决,就取消它,但是我不知道如何取消promise。 谢
本文向大家介绍JavaScript数组中的第一个元素和最后一个元素?,包括了JavaScript数组中的第一个元素和最后一个元素?的使用技巧和注意事项,需要的朋友参考一下 数组是一组元素。每个元素都有其自己的 索引值。我们可以使用这些索引访问任何元素。但是,对于最后一个元素,直到知道数组中存在的元素数量,我们才知道索引。在这种情况下,我们必须使用逻辑。让我们简要地讨论这些细节。 访问第一个元素 因
本文向大家介绍Java程序来填充字节数组中的元素,包括了Java程序来填充字节数组中的元素的使用技巧和注意事项,需要的朋友参考一下 可以使用java.util.Arrays.fill()方法将元素填充到字节数组中。此方法将所需的字节值分配给Java中的字节数组。所需的两个参数是数组名称和要存储在数组元素中的值。 演示此的程序如下所示- 示例 输出结果 现在让我们了解上面的程序。 首先定义字节数组b