Javascript 如何处理捕捉块,然后是承诺

Javascript 如何处理捕捉块,然后是承诺,javascript,node.js,es6-promise,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(fal

我有以下代码

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);
});
即使我捕获了拒绝响应,也会抛出以下错误

获取错误错误(节点:11252)未处理PromisejectionWarning:错误 (节点:11252)未处理的PromisejectionWarning:未处理的承诺 拒绝。此错误源于在异步 函数没有catch块,或者拒绝了 未使用.catch()处理。(拒绝id:1)(节点:11252)[DEP0018] 弃用警告:未处理的承诺拒绝被弃用。在里面 未来,未经处理的拒绝承诺将终止合同 具有非零退出代码的Node.js进程

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

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);
});
输出:

有错误


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

这里的关键一点——也是使用承诺的关键一点——是
然后
捕获
创建新的承诺。因此,被拒绝但未得到处理的承诺是由
然后
创建的:

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);
});
这是您看到承诺链的原因之一:

在那里,仍然创建了三个承诺(原始的来自
请求
,一个来自
然后
,一个来自
捕获
),但所有这三个承诺的拒绝都由最终的
捕获
处理程序处理

then
catch
创建的承诺如下:

  • 如果基础承诺解决:
    • 如果没有
      处理程序,则使用原始承诺中的解决方案进行解决
    • 如果有
      处理程序,则调用它:
      
      • 如果处理程序返回一个thenable(类似于承诺的对象),则连接到它并根据该thenable是解析还是拒绝来解析或拒绝
      • 如果处理程序返回非thenable值,请使用该值进行解析
      • 如果处理程序抛出错误,请使用该错误拒绝
  • 如果基础承诺拒绝:
    • 如果没有
      catch
      处理程序,则拒绝原始承诺的拒绝
    • 如果有一个
      catch
      处理程序,调用它并完全按照上面的
      处理程序执行(根据返回或抛出的内容解决或拒绝)
promise.then()
创建一个新的promise,其结算取决于
promise
。当拒绝
promise
时,由
promise.then()
创建的隐式承诺也会被拒绝,并且没有
catch()
子句来处理错误

您需要做的是将
.catch()
链接到
promise返回的promise。然后()

功能请求(状态){
返回新承诺((解决、拒绝)=>{
设置超时(()=>{
如果(状态){
决心(“成功”);
}否则{
拒绝(“错误”);
}
}, 1000);
}); 
}
让承诺=要求(虚假);
承诺。然后(回复=>{
console.log('response',response);
}).catch((错误)=>{
log('got Error',err);

});请查看以下两种处理方法

在第一种方法中,一旦在“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);
  }
);

这在浏览器上是如何工作的?我只回答了最初的问题,没有任何错误。但它在节点上给出了错误。@是否确实正确运行了它?我的原始问题在浏览器上出现了预期的错误。@Ritesh-什么浏览器?现在所有主流的现代浏览器都会报告未经处理的拒绝,但如果您使用的是旧版本(或polyfill…)。(polyfills很难正确报告未处理的拒绝,因为它基本上必须由垃圾收集器完成。)我在chrome控制台上运行了它。。我的chrome版本是68。0@Ritesh-你等了多久?该错误在(非常短暂的)延迟后显示。控制台中是否有任何活动的筛选?在任何情况下,都会有未经处理的拒绝,如果你的Chrome v68副本(它肯定能处理此问题)出于某种原因没有报告,这是非常奇怪的。Nice catch@Kirill,这是我已知的Dupirategets列表中的一个。@t.J.Crowder补充了一个简短的解释。谢谢,成交。但它并没有真正回答OP的代码(毕竟使用了
catch
)为什么会遭到未经处理的拒绝的问题。
promise
  .then(response => {
    console.log("response", response);
  })
  .catch(err => {
    console.log(err);
  });

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