Node中带有error handling的多重承诺

我怎样才能避免在Node.js中的服务调用链的嵌套地狱,我想抛出一个给定的错误,并在某些情况下退出整个链? 这是一个链的例子:

  1. 加载Mongoose对象。
  2. 如果加载失败, res.send(404) ; 如果加载成功,则转到下一个then()
  3. 呼叫第三方API来获取一些数据。
  4. 如果API调用失败,请发送正确的响应(比如,为了解决这个问题,正确的状态码是500
  5. 如果API调用成功,则呈现该页面。

     SomeMongooseModel.findOne({id:123}).exec() .then(function(response) { // If group is empty, would like to res.send(404) and resolve the // promise immediately. }) .then(function(response) { // Hit 3rd party API to retrieve data. If there's an issue, return // response code of 500 and resolve promise immediately. // Assuming the API call was a success, build out an object and render // the page like so: res.render('some.template', {data: some_data}); }); 

我认为这是我想要实现的一个体面的例子,但是如果我们有更多的asynchronous调用来处理呢? 我们怎样才能立即退出? 我做了一些search,我知道我还有很多东西需要学习,但是我没有find立即退出连锁店的能力。

面对这个问题,我通常把所有的东西都分解成一些函数,然后我把这个函数传递给这个promise。 用好的名字也有利于阅读:

 function resolveNotFoundIfGroupEmptyOrForwardResponse( response ) { res.send(404) } function hit3rdPartyApiBasedOnResponse( response ) { // throw exception if there is an issue. next step will run the failure state } function render500() { ... } function renderTemplateWithData( some_data ) { res.render('some.template', {data: some_data}); } SomeMongooseModel.findOne({id:123}).exec() .then( resolveNotFoundIfGroupEmptyOrForwardResponse ) .then( hit3rdPartyApiBasedOnResponse ) .then( renderTemplateWithData, render500 ) .done(); 

如果函数需要input参数,而不是来自承诺链,那么我通常会做一个返回函数的函数。

 function doStuffWithParamsCommingFromTwoSides( main_input ) { return function( promise_input ) { ... } } then( doStuffWithParamsCommingFromTwoSides( "foobar" ) ) 

遵循Promises / A +规范, then步骤如下所示:

 promise.then(onFulfilled, onRejected, onProgress) 

每当引发exception时,下一步将运行onRejected 。 最终冒泡的done ,也可以用来赶上例外泡沫。

 promise.done(onFulfilled, onRejected, onProgress)