Promise.all中承诺的多次拒绝,究竟发生了什么?

时间:2017-12-01 11:54:01

标签: javascript node.js promise node-pg-pool

Promise.all([iterable])是全有或全无的,这意味着当iterable中的每个promise解析时它返回的promise都会解析,或者只要其中一个promise拒绝,它就会拒绝,第一个承诺拒绝(doc)的原因。

但如果 iterable 的多个承诺拒绝,会发生什么?

在VSCode中,我尝试了以下示例,故意使 foo() bar()承诺失败。当我在VSCode中调试时,我在* catch上收到错误(错误=> Promise.reject('错误查询栏()'))*说发生了异常,我不明白为什么。

我认为这是因为当我调用Promise.reject时,Promise.all已经收到来自foo函数的拒绝但也失败了,但目前尚不清楚发生了什么。

如果我在调试选项中禁用“Uncaught Exceptions”断点,则异常不再显示。

这到底发生了什么?

function foo() {
  return pool.query('insert_test into test (value) values (20)')
    .then(() => client.query('insert into test (value) values (21)'))
    .catch(err => Promise.reject('error query bar()'))
}

function bar() {
  return pool.query('insert_test into test (value) values (20)')
    .then(() => client.query('insert into test (value) values (21)'))
    .catch(err => Promise.reject('error query bar()'))
 }

 Promise.all([foo(), bar()])
   .then(results => {
     console.log(results)
   })
   .catch(err => {
     console.log(err)
   });

这是我看到的启用了Uncaught Exceptions的屏幕截图。 enter image description here

2 个答案:

答案 0 :(得分:3)

  

但是,如果迭代的多个承诺拒绝,会发生什么?

第一次拒绝获胜并获得拒绝Promise.all承诺的理由。 “第一”在这里意味着“最早发生”,如果承诺已经在Promise.all访问它们时被拒绝,则迭代顺序很重要。

随后的拒绝将被忽略。

  

如果我在调试选项中禁用“Uncaught Exceptions”断点,则异常不再显示。

这很奇怪。被忽略的拒绝不应导致未处理的拒绝(或未捕获的异常)。

答案 1 :(得分:-1)

@smellyarmpits如果要防止剩余的诺言的未捕获异常在第一个诺言被拒绝后 const promiseAll = async (promises: Promise<any>[]) => { let oneHasRejected = false const onReject = (err: any) => { if (oneHasRejected) { oneHasRejected = true return Promise.reject(err) } else { return Promise.resolve() } } return Promise.all(promises.map((p) => p.then((r) => r, onReject))) } 被拒绝后被拒绝,则可以尝试Promise.all的自定义实现这样的人(打字稿):

class First:
    @classmethod
    def hello(self):
        print(123)

class Second:  
    @classmethod
    def hello(cls):
        print(123)

obj1 = First()
obj2 = Second()

print(obj1.hello())
print(obj1.hello())