如何替换书架中嵌套的 .then() 函数

How to replace nested .then() function in bookshelf

我是 node.js 的新手,我在删除 bookshelf.js 函数内的多个嵌套 .then() 时遇到了问题。

下面的代码是我现在正在处理的。现在它工作正常,但我需要添加超过 20 个嵌套的 .then() 来完成项目。因此,我试图在它变得疯狂之前将 .then() 替换为其他方法。

如有任何帮助或提示,我们将不胜感激。

   getItem: function (req, res, next) {

        DepartmentCollection.forge()
        .fetch({
              debug: true     
        })
        .then(function(collection) {
             new GlossaryTerm({'GlossaryTermID': req.params.id}).fetch({
                    withRelated: ['department'],
                    debug: true     
           })
              .then(function(model) {
                    if ("undefined" === typeof collection) { console.log("step 2: variable is undefined") }
                    else { console.log("step 2: variable is defined") };

                    res.render('glossary/glossary-term-detail',{domain:'GlossaryTerm', title: 'Glossary Term Detail',
                                                                  data: model, department_data: collection }); 

              }).catch(function(error) {
                    console.log(error);
                    res.send('An error occured');
              }); 

        }).catch(function(error) {
              console.log(error);
              res.send('An error occured');
        });

  }

我强烈推荐 co 库。

npm install co --save

然后您可以使这些调用 'appear' 同步并避免这种金字塔式的厄运类型问题。

const co = require('co');

co(function* () {
  const resultOne = yield asyncCallOne();
  const resultTwo = yield asyncCallTwo();

  try {
    const resultThree = yield asyncCallThree();
  } catch (error) {
    console.log(error);
  }

  // and so on, and so on.
});

通常你不需要嵌套thenables。 thenable 的结果成为下一个的输入。所以大多数时候你可以 chain 它们而不是 nesting:

getItem: function (req, res, next) {
  // Creating a closure for storing intermediate then() results
  let collection;
  // Making getItem() a promise itself
  return DepartmentCollection
    .forge()
    .fetch({
      debug: true     
    })
    .then(function(fetched_collection) {
      collection = fetched_collection;
      if ("undefined" === typeof collection) { 
        console.log("step 2: variable is undefined")
      } else { 
        console.log("step 2: variable is defined")
      }
      return new GlossaryTerm({'GlossaryTermID': req.params.id})
        .fetch({
                withRelated: ['department'],
                debug: true     
        });
    })    
    .then(function(model) {
      res.render('glossary/glossary-term-detail', {
        domain:'GlossaryTerm', 
        title: 'Glossary Term Detail',
        data: model, 
        department_data: collection }); 
    })
    .catch(function(error) {
      console.log(error);
        res.send('An error occured');
    }); 
}

一个例外是当逻辑必须被拆分成更多的链时,这些链使用不同的方式提供结果。在这些情况下,建议将复杂的逻辑移动到另一个函数(返回承诺):

所以这个

function complex() {
  return f1()
    .then(x => {
      if (!x) {
        return f2()
          .then(f3);
      }
      return f3();
    })
    .then(...);      
}

变成这样:

function complex() {
  function f4(x) {
    if (!x) {
      return f2()
        .then(f3);
    }
    return f3();
  }
  return f1()
    .then(f4)
    .then(...);    
}