第一次成功解决ES6承诺 [英] Resolve ES6 Promise with first success?

查看:133
本文介绍了第一次成功解决ES6承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对ES6 Promise API中的某些东西感到困惑。我可以看到一个明确的用例来同时提交多个异步工作,并在第一次成功时解决。例如,这将服务于多个等效服务器可用的情况,但有些服务器可能出现故障,而其他服务器可能会出现故障,而其他服务器负载较重,而且其他服务器负载缓慢,因此我的目标是从第一个服务器获得响应以避免其他(是的,我知道这是客户端从服务器角度出发的一种讨厌的方式,但最终用户是非常好的。)



然而,就我而言看,我有全部或种族的行为。 所有行为似乎等待所有请求完成,这意味着我必须等待最慢,即使服务器已经完成(实际上,我可能需要等待超时,这将是一场灾难对于这种情况)。然而,种族行为似乎让我第一次完成,如果这是一个失败,也是一场灾难。



API中有什么可以允许raceToSuccess的行为,还是手工建立它。对于这件事情,我将如何手工构建它?



作为一个附注,我在Java 8 CompletableFuture中发现了同样的难题,似乎是一个非常平行的API。那么,我在哲学层面上缺少某些东西?

解决方案

这是一个经典的例子,反转你的逻辑使它更加清晰。在这种情况下,你的种族是你想要拒绝的行为其实是成功的行为。

  function oneSuccess(promises) {
return Promise.all(promises.map(p => {
//如果一个请求失败,将其作为一个分辨率计算,这样它将保持
//等待其他可能的成功
返回p.then(
val => Promise.reject(val),
err => Promise.resolve(err)
);
))然后(
//如果'.all'解决了,我们刚刚得到一个错误数组
errors => Promise.reject(errors),
//如果'.all'被拒绝,我们得到了我们想要的结果
val => Promise.resolve val)
);
}


I'm puzzled by something in the ES6 Promise API. I can see a clear use case for submitting multiple async jobs concurrently, and "resolving" on the first success. This would, for example, serve a situation where multiple equivalent servers are available, but some are perhaps down, and others heavily loaded and slow, so my goal would be to get a response from the first one to succeed, and ignore the rest (yes, I know this is an obnoxious way for a client to behave from a server's perspective, but it's great for the end user ;)

However, as far as I can see, I have either "all" or "race" behaviors to play with. The "all" behavior seems to wait until all the requests have completed, which means that I have to wait for the slowest, even if a server has already completed (indeed, I might have to wait for a timeout, with would be a disaster for this scenario.) The "race" behavior, however, seems to give me the first to complete, which if that happens to be a failure, is also a disaster.

Is there something in the API that permits a "raceToSuccess" kind of behavior, or do I have to build it by hand. For that matter, how would I build it by hand?

As a side note, I found the same puzzle in the Java 8 CompletableFuture, which seems to be a closely parallel API. So, am I missing something at a philosophical level?

解决方案

This is a classic example where inverting your logic makes it much clearer. Your "race" in this case is that you want your rejection behavior to in fact be success behavior.

function oneSuccess(promises){
  return Promise.all(promises.map(p => {
    // If a request fails, count that as a resolution so it will keep
    // waiting for other possible successes. If a request succeeds,
    // treat it as a rejection so Promise.all immediately bails out.
    return p.then(
      val => Promise.reject(val),
      err => Promise.resolve(err)
    );
  )).then(
    // If '.all' resolved, we've just got an array of errors.
    errors => Promise.reject(errors),
    // If '.all' rejected, we've got the result we wanted.
    val => Promise.resolve(val)
  );
}

这篇关于第一次成功解决ES6承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆