如何优雅地检测所有Promise被拒绝的时间?

时间:2018-01-18 14:39:43

标签: javascript promise

如果所有Promise被拒绝,我如何执行功能?我认为Promise.all并不合适,除非我拒绝承诺而不是解决它们。但在我的情况下这样做是不合逻辑的,因此使代码更难以遵循。我想使用与promise.all类似的语法。因为我发现这种语法非常容易理解。



// some promises to play with
let promise1 = new Promise((resolve, reject) => {setTimeout(resolve, 100)});

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

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

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

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

// run code (on .then) if all promises are resolved
Promise.all([promise1, promise2, promise3])
  .then(() => console.log('1: all promises have been resolved'))
  .catch(() => console.log('1: one or more promises have been rejected'));

// run code (on .catch) if one or more promises are rejected
Promise.all([promise1, promise2, promise4])
  .then(() => console.log('2: all promises have been resolved'))
  .catch(() => console.log('2: one or more promises have been rejected'));

// the issue:
// run code if one or more promises are resolved
//
// How can I execute a function when all 
// promises have been rejected?
// I think Promise.all isn't 
// suited, unless I reject the promises instead of 
// resolving them. But it would not be logical to do 
// that in my situation, 
// and thus make the code trickier to follow
// I would like to use a similar syntax
// as promise.all.

// these promises should return '3: one or more promises have been resolved' and '4: all promises have been rejected'
Promise.all([promise2, promise4])
  .then(() => console.log('3: one or more promises have been resolved'))
  .catch(() => console.log('3: all promises have been rejected'));
  
  Promise.all([promise5, promise4])
  .then(() => console.log('4: one or more promises have been resolved'))
  .catch(() => console.log('4: all promises have been rejected'));




3 个答案:

答案 0 :(得分:2)

[promise1, promise2, promise3 /*...*/]
 .reduce((chain, promise) => chain.catch(() => promise))
 .catch(() => console.error("all failed"));

这构建了一个承诺链。

答案 1 :(得分:0)

尝试承诺 - 任何npm模块或bluebird等效模块。您可以在至少一个承诺已解决时停止,或者如果未解决则失败:

Promise.any([....])
.then(() => "bad, at least one resolved"), () => "good, all rejected")

答案 2 :(得分:0)

如果我理解正确你想要运行一个功能当且仅当所有承诺都被拒绝并且你想要一些像<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>io.fabric8</groupId> <artifactId>fabric8-maven-plugin</artifactId> <version>3.5.33</version> <configuration> <verbose>true</verbose> <images> <image> <name>gcr.io/myid/demo123</name> </image> </images> </configuration> <executions> <execution> <id>fmp</id> <goals> <goal>resource</goal> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 那样优雅的东西时......?然后你仍然可以使用Promise.all(),但你需要一个小帮助函数来Promise.all()承诺。

invert

现在你的三个拒绝承诺会做你想要的。

var invert = pr => pr.then(v => Promise.reject(v), x => Promise.resolve(x));

如果您的任何承诺通过某种方式解决,那么如果您愿意,您可以在var promises = [new Promise((resolve, reject) => {setTimeout(reject, 100, "1st promise rejected")}), new Promise((resolve, reject) => {setTimeout(reject, 100, "2nd promise rejected")}), new Promise((resolve, reject) => {setTimeout(reject, 100, "3rd promise rejected")})], invert = pr => pr.then(v => Promise.reject(v), x => Promise.resolve(x)); Promise.all(promises.map(invert)) .then(errs => errs.forEach(err => console.log(err)));阶段获得解决方案。