Promise.race()方法

选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。

Promise.race()方法

Promise.race() 方法对监控多个 Promise 提供了一种稍微不同的方式。该方法也接受一个可迭代的Promise ,监控并返回一个 Promise,一旦第一个 Promise settled,返回的 Promise 就会settled。Promise.race() 方法不是像 Promise.all() 方法那样等待所有的 Promise 都被解决,或者像 Promise.any() 那样只对第一个解决的 Promise 进行短路,而是在任意一个Promise settled(fulfilled or rejected)立即返回一个适当的 Promise。 例如:

let promise1 = Promise.resolve(42);

let promise2 = new Promise(function(resolve, reject) {
  resolve(43);
});

let promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(44);
  }, 100);
});

let promise4 = Promise.race([promise1, promise2, promise3]);

promise4.then(value => console.log(value));

在这段代码中,第一个 Promise (promise1) 创建为fulfilled的 Promise,而其他 Promise 则在调度作业。 然后用 42 的值调用 promise4 的fulfillment handler并忽略其他proimise。 传递给 Promise.race() 的 Promise 确实是在竞争,看哪个先解决。 如果第一个settled的promise fulfilled,那么返回的promise也被履行; 如果第一个要settled Promise rejected,则返回的 Promise rejected。 这是一个rejection的例子:

let promise1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve(42);
  }, 100);
});

let promise2 = new Promise(function(resolve, reject) {
  reject(43);
});

let promise3 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve(44);
  }, 50);
});

let promise4 = Promise.race([promise1, promise2, promise3]);

promise4.catch(reason => console.log(reason)); 

在这里,promise1 和 promise3 都使用 setTimeout() 来延迟 promise 的实现。 结果是 promise4 reject,因为 promise2 在 promise1 或 promise3 fulfilled之前rejected。即使 promise1 和 promise3 最终实现,这些结果也被忽略,因为它们发生在 promise2 rejected之后。

 

Promise.race()使用场景

Promise.race() 方法最适合用于您希望能够短路完成多种不同promise的情况。 与 Promise.any() 不同,在 Promise.any() 中,您特别希望其中一个 Promise 成功;而Promise.race()适用于第一个settled后整个promise就settled的情况 . 以下是您可能想要使用 Promise.race() 的一些情况。

构建超时操作

虽然 fetch() 函数有很多有用的功能,但它没有做的一件事是管理给定请求的超时; 请求将愉快地挂起,直到请求以一种或另一种方式完成。 您可以使用 Promise.race() 轻松创建一个包装器方法来为任何请求添加超时:

function timeout(milliseconds) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
	 reject(new Error("Request timed out."));
    }, milliseconds);
  });
}

function fetchWithTimeout(...args) {
  return Promise.race([
    fetch(...args),
      timeout(5000)
  ]);
}

const API_URL = "https://jsonplaceholder.typicode.com/users";

fetchWithTimeout(API_URL)
  .then(response => response.json())
  .then(users => console.log(users))
  .catch(reason => console.error(reason.message));

timeout() 函数类似于本章前面创建的 delay() 函数,只是它在延迟后调用 reject() 而不是 resolve()。 在这种情况下,延迟表示错误情况,因为您希望在请求花费的时间超过预期(本例中为 5000 毫秒)时得到通知。 然后 fetchWithTimeout() 函数在传递给 Promise.race() 的数组中调用 fetch() 和 timeout()。 如果对 fetch() 的调用比超时时间长,则返回的 Promise 将rejected,以便您可以适当地处理失败。

请记住,即使 fetchWithTimeout() 会在请求花费的时间超过指定的超时时间时reject,但该请求不会被取消。 即使响应将被忽略,它将继续在幕后等待响应。

版权声明:著作权归作者所有。

相关推荐

检测iPhone X机型的方法

iPhone X即将上市。为了更好适配iPhone X,我们可能需要对iPhone做机型的判断。下面介绍两种方法:根据屏幕尺寸和方向判断这是iPhone机型列表。Swift 3if UIDevice().userInterfaceIdiom == .phone {      &n

Python安全创建目录的方法

在介绍Python安全创建目录之前,先举一个不安全创建目录的方式:if not os.path.exists(directory):     os.makedirs(directory) 在例子里,先判断目录是否存在,然后创建目录。这种方式是不安全的,它会导致竞争条件。在os.path.exists()和os.makedirs()之间的时

Swift 3/4缩放UIImage的方法

给UIImage添加extension(兼容Swift3 和Swift 4)extension UIImage {     func scaled(withSize size: CGSize) -> UIImage {   &nbs

Python比较字典的巧妙方法

Python里比较两个字典,可以比较两个字典有多少个是相同的键值对的。示例:>>> x = dict(a=1, b=6,c=3) >>> y = dict(a=2, b=2) >>> shared_items = set(x.items

Spring MVC获取请求header的方法

在Spring MVC有两种方法可以用来获取请求头Header的值。方法一、通过在方法的参数添加注解@RequestHeader示例如下:@Controllerpublic class RequestHeaderDemoController { @Autowired private HttpServletRequest request; @GetMapping("/prin

Ubuntu禁用systemd-resolved的方法

1、禁用并停止systemd-resolved的服务:sudo systemctl disable systemd-resolved.servicesudo systemctl stop systemd-resolved2、在/etc/NetworkManager/NetworkManager.conf文件的[main]中添加下面一行:dns=default3、删除链接:/etc/resolv.c

Python3 词典按值排序的方法

Python 3.6按值排序:x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}{k: v for k, v in sorted(x.items(), key=lambda item: item[1])}{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}按键排序只需要把item[1]改为item[0]x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}{

CKEditor5正确添加插件的方法

CKEditor5添加插件错误ckeditor-duplicated-modules本来想在CKEditor 5的ckeditor5-build-classic添加一个Code Block插件,按官方文档,先安装@ckeditor/ckeditor5-code-blocknpm install --save @ckeditor/ckeditor5-code-block然后再代码中引入使用:impo

CKEditor5 Observable——装饰方法

上一节我们学习了在CK5中,如何绑定多个属性以及绑定多个Observable对象,今天我们学习如何装饰方法。 首先,我们提出一个问题,为什么会有装饰方法呢?以及什么叫做装饰?所谓装饰,就是在不改变原来方法功能的前提下,增加方法的功能,众所周知在java的IO流中,就有很多地方用到了装饰。 而在CK5中,装饰是什么意思呢?请看下面这段话:Decorating object met