【问题标题】:Multiple promises in Node with error handling带有错误处理的 Node 中的多个 Promise
【发布时间】:2014-08-22 13:09:00
【问题描述】:

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

  1. 加载 Mongoose 对象。
  2. 如果加载失败,res.send(404);如果加载成功,转到下一个then()
  3. 调用第 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});
    });
    

我认为这是我正在努力实现的一个很好的例子,但是如果我们有更多的异步调用需要处理呢?我们如何才能立即退出链条?我做了一些搜索,我知道我还有很多东西要学,但我没有找到立即退出链条的能力。

【问题讨论】:

  • 我应该补充一点,我尝试过使用.catch()...,但收到Object #<Promise> has no method 'catch' 的错误 - 似乎这是只有某些对象提供的糖,而不是承诺规范的必要条件?
  • 调用 promise 提供的 reject() 方法应该会取消后续的链式调用。
  • @dandavis:promise 对象不应该有.reject 方法。还是这是一些不起眼的自制 promise 库?
  • @Bergi:reject 是 Promise 构造函数的第二个参数,它如何提供给实例是特定于实现的。

标签: javascript node.js mongoose promise


【解决方案1】:

当遇到这种情况时,我通常将所有内容分成函数,然后将引用传递给 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();

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

function doStuffWithParamsCommingFromTwoSides( main_input ) {
   return function( promise_input ) {
         ...
   }
}

then( doStuffWithParamsCommingFromTwoSides( "foobar" ) )

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

promise.then(onFulfilled, onRejected, onProgress)

每当抛出异常时,下一步将运行onRejected。最终冒泡到done,它也可以用来捕获异常气泡。

promise.done(onFulfilled, onRejected, onProgress)

【讨论】:

  • 这很有帮助!感谢分享。我不习惯在这样的路由中有一堆函数的想法,但我想对于这样的调用,这是更明智的方法。
猜你喜欢
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 2016-05-08
  • 2019-02-17
  • 2021-01-23
  • 2022-11-22
  • 2019-01-05
  • 2016-04-20
相关资源
最近更新 更多