【问题标题】:How to avoid nesting structure of callbacks with promises? [finished]如何避免带有承诺的回调嵌套结构? [完成的]
【发布时间】:2018-06-03 17:11:06
【问题描述】:

我使用 Promise 来避免回调创建的嵌套结构。

但是在这段代码中我仍然有一些嵌套。是我做错了什么还是在这种情况下这是不可避免的?

在这种情况下,我想检查配置文件是否存在,如果不存在,我想创建它。

  DB.getProfile(id_google).then((resGet) => {
    if(!resGet[0]){
      console.log('PROFILE - NOT FOUND - MUST CREATE');

      DB.createProfile(id_google, email, name, pic_url).then((resCreate)=>{
        console.log('PROFILE CREATED');
      }).catch((error) => {
        console.log('ERROR - createProfile() Failed: ', error);
      });

    } else {
      console.log('PROFILE FOUND LOCALLY');
      console.log(resGet[0]);
      return done(null, resGet[0])
    }
  }).catch((error) => {
      console.log('ERROR - getOrCreateProfile() Failed: ', error);
  });
};

【问题讨论】:

  • 您可以在应用程序中使用 async/await 代替 Promise 吗?
  • 是的,nesting is pretty much unavoidable 用于条件语句。
  • 你真的应该从你的所有函数中return(做出承诺)而不是调用done回调。这样,您就不会忘记调用它(在创建配置文件时)。
  • @boysimpledimple async/await 不能“代替”promise。它与 with 承诺一起使用,而不是 then 回调。
  • 如果你这么认为,那么我建议你阅读this。它解释了为什么使用回调/承诺以及如何使用它们。如果 resGet[0] 是假的并且 getProfile 被拒绝,您的函数将在 undefined 中解析。

标签: javascript express promise passport.js


【解决方案1】:

您可以使用多个then返回和链接

DB.getProfile(id_google)
    .then((resGet) => {
        if (!resGot[0]) {
            return DB.createProfile(id_google, email, name, pic_url);
        }
        return resGot[0];
    })
    .then((res) => {
        callback(null, res)
    })
    .catch((error) => {
        console.log('ERROR - getOrCreateProfile() Failed: ', error);
    });

如果resGot[0] 存在,则返回它,而在第二个then 中,变量res 就是那个值。如果没有,则返回createProfile 的承诺,res 的值就是该函数返回的值

【讨论】:

    【解决方案2】:

    有时,将代码归结为基本要素会有所帮助:

    getProfile
      if not found, 
        createProfile
           return profile
      else
        done profile
    

    大概,您希望将createProfile 与承诺的其余部分放在同一个链中。

    我将结构更改为:

    getProfile
      if found, return profile 
      createProfile
        return profile
    then
      done(profile)
    

    在这种情况下,实际上不可能只有一级嵌套。但是您可以减少一定程度的嵌套。

    DB.getProfile(id_google)
    .then((resGet) => {
        if(resGet[0]) {
          console.log('PROFILE FOUND LOCALLY');
          return resGet[0];
        }
        console.log('PROFILE - NOT FOUND - MUST CREATE');
        return DB.createProfile(id_google, email, name, pic_url)
        .then((resCreate)=>{
          console.log('PROFILE CREATED');
          return resCreate[0]; //Assuming resCreate looks like resGet
        })
      }
    })
    .then(profile=> {
        //The done function which belongs to passport is called once here.
        console.log(profile);
        return done(null, resGet[0])
    })
    .catch((error) => {
        console.log('ERROR - getOrCreateProfile() Failed: ', error);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-07
      • 2018-10-15
      • 2019-05-22
      相关资源
      最近更新 更多