Javascript 理解promise.race()用法
据我所知,有两种选择:Javascript 理解promise.race()用法,javascript,jquery,ajax,es6-promise,Javascript,Jquery,Ajax,Es6 Promise,据我所知,有两种选择: 好的,我知道promise.all()做什么。它并行运行promissions,。然后,如果两者都成功解析,则将为您提供值。以下是一个例子: Promise.all([ $.ajax({ url: 'test1.php' }), $.ajax({ url: 'test2.php' }) ]) .then(([res1, res2]) => { // Both requests resolved }) .catch(error => {
。然后,如果两者都成功解析,则
将为您提供值。以下是一个例子:
Promise.all([
$.ajax({ url: 'test1.php' }),
$.ajax({ url: 'test2.php' })
])
.then(([res1, res2]) => {
// Both requests resolved
})
.catch(error => {
// Something went wrong
});
但是我不明白承诺了什么。race()
到底应该做什么?换句话说,不使用它有什么区别?假设:
$.ajax({
url: 'test1.php',
async: true,
success: function (data) {
// This request resolved
}
});
$.ajax({
url: 'test2.php',
async: true,
success: function (data) {
// This request resolved
}
});
看到了吗?我没有使用过promise.race()
,它的行为类似于promise.race()
。无论如何,有没有简单明了的例子告诉我什么时候应该使用promise.race()
?正如您所看到的,race()
将返回首先解析或拒绝的promise实例:
var p1=新承诺(函数(解析、拒绝){
setTimeout(解析,500,“一”);
});
var p2=新承诺(函数(解析、拒绝){
setTimeout(解析,100,'two');
});
Promise.race([p1,p2])。然后(函数(值){
console.log(值);/“两个”
//两者都可以解决问题,但p2更快
});代码>下面是一个简单的示例,可以理解promise.race()
的用法:
假设您需要从服务器获取一些数据,如果数据加载时间过长(比如15秒),您希望显示错误
您可以通过两个承诺调用promise.race(),第一个是ajax请求,第二个是简单的设置超时(()=>resolve(“ERROR”),15000)
这是构建超时系统的一部分,其中:
Promise.race
的结果远不如副作用重要(不过,这是一种代码气味)
//300毫秒感觉“瞬间”,闪烁不好
函数getUserInfo(用户){
返回新承诺((解决、拒绝)=>{
//在1500时,它更真实,但900更适合测试
setTimeout(()=>resolve(“用户数据”)、Math.floor(900*Math.random());
});
}
函数showUserInfo(用户){
返回getUserInfo()。然后(info=>{
日志(“用户信息:”,信息);
返回true;
});
}
函数showSpinner(){
console.log(“请稍候…”)
}
功能超时(延迟、结果){
返回新承诺(解决=>{
setTimeout(()=>解析(结果),延迟);
});
}
Promise.race([showUserInfo(),超时(300)])。然后(显示=>{
如果(!显示)showSpinner();
});代码>我已经将其用于请求批处理。为了长时间执行,我们不得不将成千上万条记录分批处理。我们可以并行进行,但不希望挂起的请求数量失控
Race允许我们保持固定数量的并行承诺运行,并在完成时添加一个以替换
const _ = require('lodash')
async function batchRequests(options) {
let query = { offset: 0, limit: options.limit };
do {
batch = await model.findAll(query);
query.offset += options.limit;
if (batch.length) {
const promise = doLongRequestForBatch(batch).then(() => {
// Once complete, pop this promise from our array
// so that we know we can add another batch in its place
_.remove(promises, p => p === promise);
});
promises.push(promise);
// Once we hit our concurrency limit, wait for at least one promise to
// resolve before continuing to batch off requests
if (promises.length >= options.concurrentBatches) {
await Promise.race(promises);
}
}
} while (batch.length);
// Wait for remaining batches to finish
return Promise.all(promises);
}
batchRequests({ limit: 100, concurrentBatches: 5 });
摘要:
Promise.race
是一个JS内置函数,它接受一组Promise(例如Array
)作为参数。然后,当iterable中传递的承诺中的一个被解析或拒绝时,此函数异步返回一个承诺
示例1:
var promise1=新承诺((解决、拒绝)=>{
setTimeout(()=>resolve('Promise-one'),500);
});
var promise2=新承诺((解决、拒绝)=>{
setTimeout(()=>resolve('Promise-two'),100);
});
承诺。种族([promise1,promise2])。然后((值)=>{
console.log(值);
//双方都下定决心,但承诺2比承诺1快
});
让我们来看看下面的Promise.race
的示例解决方法
const race = (promises) => {
return new Promise((resolve, reject) => {
return promises.forEach(f => f.then(resolve).catch(reject));
})
};
您可以看到race
函数执行所有承诺,但谁先完成,谁将使用包装器Promise
解决/拒绝您的网络呼叫,为什么不使用超时设置?@JaromandaX是对的。在您的示例中,在ajax请求中使用timeout
会更好。无论如何,谢谢您,upvote然而,fetch
方法调用仍在继续,但无论何时返回,输出都将被丢弃。超时应该会取消挂起的请求。与承诺.任何
相比有什么区别吗?@Dominic区别在于承诺.种族
会更快,原因如下:承诺.种族
会在您提供的任何承诺解决后立即解决,无论它们是履行还是拒绝<代码>承诺。任何
都会在您提供的任何承诺兑现或全部被拒绝后立即结算,在这种情况下,它会被AggregateError拒绝。因此,在“全部拒绝”场景中,Promise.any
将变慢,因为它将等待所有承诺被拒绝。差别不大,但仍然是。很好的例子,@Iiridayn。不过,关于第一个问题,我很好奇为什么您选择将您的timeout
视为一个异常,浪费执行setpinner()的catch
块,而不是像var delayedSpinner=(ms)=>new Promise((resolve,reject)=>setTimeout(resolve,ms,'please wait…);Promise.race([showUserInfo(),delayedSpinner(300)])
。这样,您仍然可以正确地处理来自showUserInfo
的异常,而不是默默地删除它们,从而永远显示微调器。@JayAllen我不想在显示微调器之前取消超时或检查共享状态。我已经对它进行了更新,以解析一个布尔值(console.log返回的undefined
为false),这样您就可以在生产代码中使用它,而修改的代码就更少了