如何处理捕获块然后承诺

时间:2018-09-21 07:35:21

标签: javascript node.js es6-promise

我有以下代码

function request(status){
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if(status){
        resolve('Success');
      } else {
        reject('error');
      }
    }, 1000);
  }); 
}


let promise = request(false);

promise.then( response => {
  console.log('response' , response);
});

promise.catch( (err) => {
  console.log('got Error', err);
});

即使我捕获了拒绝响应,也会引发以下错误

  

got Error错误(节点:11252)UnhandledPromiseRejectionWarning:错误   (节点:11252)UnhandledPromiseRejectionWarning:未处理的承诺   拒绝。该错误是由抛出异步内部引起的   没有捕获块或拒绝承诺   未使用.catch()处理。 (拒绝ID:1)(节点:11252)[DEP0018]   DeprecationWarning:已弃用未处理的承诺拒绝。在   未来,未处理的承诺拒绝将终止   具有非零退出代码的Node.js进程。

但是如果我删除了 then 块,那么它可以正常工作, 控制台上没有堆栈跟踪错误

function request(status){
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if(status){
        resolve('Success');
      } else {
        reject('error');
      }
    }, 1000);
  }); 
}


let promise = request(false);

promise.catch( (err) => {
  console.log('got Error', err);
});

输出:

  

得到错误错误

我不明白为什么它会以这种方式工作?

3 个答案:

答案 0 :(得分:5)

这里的关键,也是使用承诺的关键之一,是 thencatch创建新的承诺。因此,无法兑现的诺言是then创建的:

let promise = request(false);

promise.then( response => {          // Creates new promise, rejection isn't handled
  console.log('response' , response);
});

promise.catch( (err) => {            // Creates new promise
  console.log('got Error', err);
});

这是您看到承诺链条的原因之一:

request(false)
.then( response => {
  console.log('response' , response);
})
.catch( (err) => {
  console.log('got Error', err);
});

那里仍然创建了三个承诺(来自request的原始承诺,来自then的一个承诺和来自catch的一个承诺),但是所有这三个承诺均由拒绝者处理最后的catch处理程序。

thencatch创建的承诺是这样的:

  • 如果基本承诺得以解决:
    • 如果没有then处理程序,请使用原始诺言中的解决方法进行解决
    • 如果有then处理程序,请调用它:
      • 如果处理程序返回 thenable (类似promise的对象),请连接到该对象并根据thenable解析还是拒绝来解析或拒绝
      • 如果处理程序返回一个非 thenable 值,请使用该值进行解析
      • 如果处理程序引发错误,则拒绝该错误
  • 如果基本承诺拒绝:
    • 如果没有catch处理程序,则拒绝原始诺言
    • 如果有一个catch处理程序,请调用它并完全执行上面的then处理程序(根据返回或抛出的结果进行解析或拒绝)

答案 1 :(得分:2)

promise.then()创建了一个新的承诺,其结算取决于promise。当promise被拒绝时,由promise.then()创建的隐式promise也被拒绝,并且没有catch()子句来处理错误。

您需要做的是将.catch()链接到promise.then()返回的承诺:

function request(status){
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if(status){
        resolve('Success');
      } else {
        reject('error');
      }
    }, 1000);
  }); 
}


let promise = request(false);

promise.then( response => {
  console.log('response' , response);
}).catch( (err) => {
  console.log('got Error', err);
});

答案 2 :(得分:1)

请查看以下两种处理方法。

在第一种方法中,一旦在'then'中解决了承诺,您就尝试处理承诺拒绝,否则您可以将.then()与.catch()链接起来。

还请注意,只有在答应被拒绝的情况下,才会调用然后中的err块。但是即使有其他js错误,catch块也会被调用。

promise
  .then(response => {
    console.log("response", response);
  })
  .catch(err => {
    console.log(err);
  });

promise.then(
  response => {
    console.log("response", response);
  },
  err => {
    console.log(err);
  }
);

Code Sandbox Link