简体   繁体   English

如何有条件地使用Promises执行第二项任务?

[英]How do I conditionally perform a second task using Promises?

I'm using Bookshelf.js, a Promise-based ORM module, to perform a couple database lookups. 我正在使用Bookshelf.js(一个基于Promise的ORM模块)来执行几个数据库查找。 Given a key that a user provides, I need to determine if the key matches a record in one of two tables. 给定用户提供的键,我需要确定该键是否与两个表之一中的记录匹配。 If I find it in the first table, I need to return that record. 如果在第一个表中找到它,则需要返回该记录。 However, if I don't find it in the first table, I need to look in the second table. 但是,如果我在第一个表中找不到它,则需要在第二个表中查找。 Basically, I need to conditionally execute a then block. 基本上,我需要有条件地执行then块。 How do I accomplish this using promises? 如何使用诺言来完成此任务? Here's what I currently have, which is very messy, and, in fact, I'm a little unclear about what happens if I call resolve in the first School lookup -- does the second then block execute as well? 这是我当前所拥有的,非常混乱,实际上,我不清楚如果在第一次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));
    });
};

Is there a cleaner way to write this? 有没有更清洁的方式来写这个?

You can just keep whole else logic inside then block: 您可以将所有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));
    });
};

Furthermore your code could be rewriten (shorter version) like this: 此外,您的代码可以这样重写(较短的版本):

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));

Use promises as proxies and a regular if : 使用承诺作为代理和常规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;
}

Or with coroutines which bluebird supports (bluebird ships with bookshelf): 或与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();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM