如何返回包含在函数

时间:2016-11-29 17:40:46

标签: angularjs node.js postgresql express sequelize.js

我正在构建一个为用户创建唯一网址的服务。 它应该做以下事情:

  
      
  • 查询数据库以查看用户是否已拥有该网址并将其发回
  •   
  • 如果用户没有使用用户的名字和姓氏创建网址
  •   
  • 检查数据库是否有其他人正在使用该字符串组合并附加1,2或3,具体取决于有多少其他用户拥有该名称(即JackBlack1,JackBlack2等)。      
        

    我有一个获取路由设置来检查url,如果用户还没有,我想发送一个单独的函数调用的结果(为了保持代码模块化)。     我的问题在于功能。它不会返回url字符串。我试图将url字符串保存到在函数顶部启动的变量,但它不是从sequelize查询中保存的。     这是我称之为函数的路线:

      
  •   
router.get('/link', function(req, res) {

    db.user.find({where: {id: req.user.id} })

        .then(function(user){

        if (!user.addresslink) {
            res.send(createUserLink(req.user.id,req.user.firstName,req.user.lastName));
        } else {

        res.send(user.addresslink)

        }
    })
        .catch(function(err){
            console.log(err);
            res.status(500).send('Internal database error.');
        })
})

这是createUserLink函数:

function createUserLink(userId, first, last){
    var urlString = (first + last).toLowerCase();
    var userLink;
    var count;

    db.user.findAndCountAll({where: { addresslink: { $like:  'www.website.com/' + urlString } }
         }).then(function(result){

        if(result.count > 0) {
           count = result.count + 1;
           db.user.find({where: {id: userId} }).then(function(user){
                user.updateAttributes({
                    addresslink: 'www.website.com/' + urlString + count
                }).then(function(result){

                    userLink = result.addresslink

                    return userLink;
                })

           })

        } else {
            db.user.find({where: {id: userId} }).then(function(user){
                user.updateAttributes({
                    addresslink: 'www.website.com/' + urlString
                }).then(function(result){

                    userLink = result.addresslink

                    return userLink;
                })
           })
        }
    })
  return userLink ;            
}

我假设无法从函数返回创建的url与查询的异步性质有关。创建网址后是否需要添加查询然后返回?这是我在这里的第一个问题,所以如果有什么不妥,我会提前道歉。

1 个答案:

答案 0 :(得分:0)

如果要返回createUserLink()返回的值,则需要返回实际的承诺并附加.then()以访问返回值。

目前,您正在尝试访问返回的userLink,就好像它是一个函数本身将返回值的同步函数。以下示例不向客户端返回任何内容,因为createUserLink()会立即返回userLink,这将是未定义的。

res.send(createUserLink(req.user.id,req.user.firstName,req.user.lastName));

在处理承诺时,事实并非如此。相反,承诺立即返回待处理状态,需要等待,直到状态得到满足或被拒绝。当promise完成执行后,您可以访问链接.then()

中的任何返回值

路线

在路线中,如果user.addressLinkfalsy,则我们要返回Promise返回函数createUserLink(),否则返回user.addressLink。当从then()中返回一个值时,返回的值包含在已实现的Promise中,并且调用下一个then()或者值本身将返回到链中最接近的Promise。

router.get('/link', function(req, res) {

    return db.user.find({where: {id: req.user.id} })
        .then(function(user){  
            if (!user.addresslink) 
                return createUserLink(req.user.id,req.user.firstName,req.user.lastName);
            else 
                return user.addressLink;
        })
        .then((userLink) => {
            return res.send(userLink);
        })
        .catch(function(err){
            console.log(err);
            return res.status(500).send('Internal database error.');
        })
})

createUserLink

function createUserLink(userId, first, last){
    var urlString = (first + last).toLowerCase();
    var userLink;
    var count;

    return db.user.findAndCountAll({where: { addresslink: { $like:  'www.website.com/' + urlString } }})
     .then(function(result){
        if(result.count > 0) 
           count = result.count + 1;

        return db.user.find({where: {id: userId} });
      })
      .then(function (user) {
          let addressLink = 'www.website.com/' + urlString;

          if (count > 0)
            addressLink + count;

          return user.updateAttributes({ addresslink : addressLink });
      })
      .then(function(result){
          userLink = result.addresslink

          return userLink;
      })
} 

有关承诺的其他信息,promisejs.org是了解承诺如何运作的重要资源。如果您想了解更多有关承诺的信息,我建议您这样做。