你如何防止sequelize中的嵌套查询/捕获?

时间:2016-08-29 02:21:11

标签: javascript typescript promise sequelize.js

我认为我尽可能地阻止嵌套查询,但老实说我不确定。我理解这里的调用都可以在一个select查询中执行,但我这样做是为了简化示例。

// This example is in TypeScript

// find user
User.find({where:{username:'user'}})

    // if found user
    .then(function(user) {

        return User.find({where:{username:'other_user'}})

            // if found other_user
            .then(function(other_user) {
                // do stuff
                return whatever_i_need
            }

            // if something went wrong, go straight to parent catch
            .catch(function(err) {
                // do stuff
                throw new Error()
            }
    }

    // if previous .then() returned success
    .then(function(data) {

        return User.find({where:{username:'yet_another_user'}})

            // if found yet_another_user
            .then(function(yet_another_user) {
                // do stuff
                return whatever_i_need_again
            }

            // if something went wrong, go straight to parent catch
            .catch(function(err) {
                // do stuff
                throw new Error()
            }
    }

    // if anything threw an error at any point in time
    .catch(function(err) {
        // handle the error
    }

但是,这会产生嵌套的承诺,这正是承诺要防止的。这是承诺推荐的“最大深度”,还是我错过了什么?是否有更好的方法来链接查询?

2 个答案:

答案 0 :(得分:2)

返回嵌套的promise而不是在内部块中处理它以展平结构。

User.find({where:{username:'user'}})
.then(function(user) {
  if (user) { // if found user
    // do stuff
    return User.find({where:{username:'other_user'}});
  }
  throw new Error('user not-found');
})
.then(function(other_user) {
  if (other_user) { // if found other_user
    // do stuff
    return whatever_i_need;
  }
  throw new Error('other_user not-found');
})
.then(function(data) {
  return User.find({where:{username:'yet_another_user'}})
})
.then(function(yet_another_user) {
  if (yet_another_user) { // if found yet_another_user
    // do stuff
    return whatever_i_need_again;
  }
  throw new Error('yet_another_user not-found');
}
.then(function(data){
  // do stuff
})
.catch(function(err) { // if anything threw an error at any point in time
  // handle the error
}

请注意,已解析的承诺表示查询已成功完成。这就是全部。成功的查询不能保证返回结果。空结果是已解决的承诺的有效结果。

另请注意,resolve或reject回调的返回值将使用已解析的promise进行包装,然后传递给下一个then块,从而形成有意义的promise链。感谢@ Matt关于这一点的以下后续反馈。

答案 1 :(得分:1)

两点:

  • 删除.catch(function(err) { throw new Error() }。它只会删除错误消息。
  • 您可unnest内部then来电

所以它应该是

User.find({where:{username:'user'}})
.then(function(user) {
    return User.find({where:{username:'other_user'}})
})
.then(function(other_user) {
    // do stuff
     return whatever_i_need
})
// if previous .then() returned success
.then(function(data) {
    return User.find({where:{username:'yet_another_user'}})
})
// if found yet_another_user
.then(function(yet_another_user) {
    // do stuff
    return whatever_i_need_again
})
// if anything threw an error at any point in time
.catch(function(err) {
    // handle the error
})