gpt4 book ai didi

javascript - 为 promise.all 中的每个 promise 设置超时

转载 作者:数据小太阳 更新时间:2023-10-29 05:53:46 28 4
gpt4 key购买 nike

我能够成功执行 Promise.all,并优雅地处理解决和拒绝。然而,有些 promise 会在几毫秒内完成,有些可能/可能需要一段时间。

我希望能够为 Promise.all 中的每个 Promise 设置超时,这样它最多可以尝试花费 5 秒。

getData() {
var that = this;
var tableUrls = ['http://table-one.com','http://table-two.com'];
var spoonUrls = ['http://spoon-one.com','http://spoon-two.com'];

var tablePromises = that.createPromise(tableUrls);
var spoonPromises = that.createPromise(spoonUrls);
var responses = {};

var getTableData = () => {
var promise = new Promise((resolve, reject) => {
Promise.all(tablePromises.map(that.rejectResolveHandle))
.then((results) => {
responses.tables = results.filter(x => x.status === 'resolved');
resolve(responses);
});
});
return promise;
};

var getSpoonData = () => {
var promise = new Promise((resolve, reject) => {
Promise.all(spoonPromises.map(that.rejectResolveHandle))
.then((results) => {
responses.tables = results.filter(x => x.status === 'resolved');
resolve(responses);
});
});
return promise;
};


return getTableData()
.then(getSpoonData);
}

rejectResolveHandle() {
return promise.then(function(v) {
return {v:v, status: "resolved"};
}, function(e) {
return {e:e, status: "rejected"};
});
}

createPromise(links) {
var promises = [];
angular.forEach(links, function (link) {
var promise = that._$http({
method: 'GET',
url: link + '/my/end/point',
responseType: 'json'
});
promises.push(promise);
});

return promises;
}

我试过向 createPromise() 添加超时,但这似乎不起作用。将超时设置为 300 毫秒,一些请求会持续 4 秒以上:

createPromise(links) {
var promises = [];
angular.forEach(links, function (link) {
var promise = that._$http({
method: 'GET',
url: link + '/my/end/point',
responseType: 'json'
});

promise = new Promise((resolve) => {
setTimeout(() => {
resolve(promise);
}, 300);
});

promises.push(promise);
});

return promises;
}

我可以访问 Bluebird,如果它能让事情变得更容易?

最佳答案

这是一个创建 Promise.raceAll() 函数的方案,它的工作方式类似于 Promise.all()Promise.race( ) 其中,promise 都有超时时间和值,因此如果 promise 在该时间之前未解决,它将被短路以使用传入的值解决。这实质上是将每个 promise 放入带有计时器的 Promise.race() 中。如果计时器获胜,则使用默认值解决 promise 。如果原始 promise 获胜,则使用实际 promise 结果解决。我们使用 Promise.race() 来解决第一个完成的问题(超时或原始 promise )。这是 Promise.race() 的经典用法(事实上,这是我真正用过它的唯一实际用途)。

一个典型的例子是在接下来的 15 秒内让我得到所有你能得到的结果。任何超过 15 秒的结果,只需为它们返回 null 并且不要等待它们。下面是使这个概念起作用的代码:

Promise.delay = function(t, val) {
return new Promise(resolve => {
setTimeout(resolve.bind(null, val), t);
});
}

Promise.raceAll = function(promises, timeoutTime, timeoutVal) {
return Promise.all(promises.map(p => {
return Promise.race([p, Promise.delay(timeoutTime, timeoutVal)])
}));
}

因此,您使用 Promise.raceAll() 就像 Promise.all() 一样,您向它传递了一个 promise 数组,但您还向它传递了一个 timeoutTime 和一个 timeoutValtimeoutTime 是 promise 超时之前等待的时间。 timeoutVal 是为任何超时的 promise 放入结果数组的内容(通常它会是类似 null 的东西,您可以轻松地将其识别为非真实结果) .


我不确定我完全了解您在特定代码中所做的事情,但这是使用上述代码的链接代码:

Promise.raceAll(links.map(link => {
return that._$http({
method: 'GET',
url: link + '/my/end/point',
responseType: 'json'
});
}), 5000, null).then(results => {
// process results here
// any timed out values will be null
// you can filter out the timed out results
let final = results.filter(item => !!item);
}).catch(err => {
// process any errors here
});

或者,如果你想确保 Promise.raceAll() 获得所有结果,即使某些 promise 被拒绝,你可以添加一个 .catch() 处理程序到每一个 promise :

Promise.raceAll(links.map(link => {
return that._$http({
method: 'GET',
url: link + '/my/end/point',
responseType: 'json'
}).catch(err => {
// don't let Promise.all() see a reject so it gets all results
return null;
});
}), 5000, null).then(results => {
// process results here
// any timed out values will be null
// you can filter out the timed out or rejected results
let final = results.filter(item => !!item);
}).catch(err => {
// process any errors here
});

关于javascript - 为 promise.all 中的每个 promise 设置超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48577702/

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