【问题标题】:How do I conditionally perform a second task using Promises?如何使用 Promises 有条件地执行第二个任务?
【发布时间】:2016-09-07 15:44:31
【问题描述】:

我正在使用 Bookshelf.js,一个基于 Promise 的 ORM 模块,来执行几个数据库查找。给定用户提供的键,我需要确定键是否与两个表之一中的记录匹配。如果我在第一个表中找到它,我需要返回该记录。但是,如果我在第一个表中没有找到它,我需要查看第二个表。基本上,我需要有条件地执行一个then 块。我如何使用 Promise 实现这一点?这是我目前拥有的,非常混乱,事实上,我有点不清楚如果我在第一个School 查找中调用resolve 会发生什么——第二个then 块是否也会执行?

exports.findTargetRecord = function(code){

    return new Promise(function(resolve, reject){
        Schools
        .query({ where: { code: code }})
        .fetchOne()
        .then(school => {
            if(school) return resolve(school);
            return Organizations
                    .query({ where: { code: code }})
                    .fetchOne();
        })
        .then(org => {
            if(org) return resolve(org);
            resolve(null);
        })
        .catch(err => reject(err));
    });
};

有没有更简洁的写法?

【问题讨论】:

标签: javascript node.js promise bookshelf.js


【解决方案1】:

使用 Promise 作为代理和普通的if:

exports.findTargetRecord = function(code){

  const school = Schools.query({ where: { code: code }}).fetchOne();
  school = school.then(school => 
    school || Organizations.query({ where: { code: code }}).fetchOne())
  return school;
}

或者使用 bluebird 支持的协程(bluebird 附带书架):

exports.findTargetRecord = Promise.coroutine(function*(code) {
   var school = yield Schools.query({ where: { code: code }}).fetchOne();
   if(school) return school;
   return Organizations.query({ where: { code: code }}).fetchOne();
});

【讨论】:

  • 谢谢,这更像是我想要的。它仍然不是超级干净或易于阅读,但它与我目前拥有的最不同,这为我提供了一些工作选择。
【解决方案2】:

您可以将整个 else 逻辑保留在 then 块中:

exports.findTargetRecord = function(code){

    return new Promise(function(resolve, reject){
        Schools
        .query({ where: { code: code }})
        .fetchOne()
        .then(school => {
            if(school) return resolve(school);
            return Organizations
                    .query({ where: { code: code }})
                    .fetchOne()
                    .then(org => {
                        if(org) return resolve(org);
                        resolve(null);
                    })
        })
        .catch(err => reject(err));
    });
};

此外,您的代码可以像这样重写(更短的版本):

exports.findTargetRecord = function(code){
    return Schools
            .query({ where: { code: code }})
            .fetchOne()
            .then(school => {
                if(school) return school;
                return Organizations
                        .query({ where: { code: code }})
                        .fetchOne();
            })
            .catch(err => reject(err));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2018-11-28
    • 2020-03-02
    • 2017-04-11
    • 1970-01-01
    • 2020-08-29
    相关资源
    最近更新 更多