Node中带有error handling的多重承诺
我怎样才能避免在Node.js中的服务调用链的嵌套地狱,我想抛出一个给定的错误,并在某些情况下退出整个链? 这是一个链的例子:
- 加载Mongoose对象。
- 如果加载失败,
res.send(404)
; 如果加载成功,则转到下一个then()
。 - 呼叫第三方API来获取一些数据。
- 如果API调用失败,请发送正确的响应(比如,为了解决这个问题,正确的状态码是
500
) -
如果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)