如何使用Node.js处理while循环内的异步操作?

时间:2015-06-26 22:34:09

标签: node.js mongodb asynchronous

对于Node API,我必须生成一个随机的字母数字键,这应该是唯一的并且短(我不能同时使用uuid或Mongo ObjectID)。

我认为这个逻辑:

  1. 生成密钥,
  2. 查询MongoDB是否存在密钥
  3. 如果密钥存在,请重复此过程
  4. 如果密钥不存在,请分配并回复客户端。
  5. 我当时试过了:

    do {
      key = randomKey(8);
      newGroup.key = key;
      Group.findOne({numberId: key}).then(function (foundGroup) {
        console.log("cb");
    
        if (! foundGroup) {
          console.log("not found")
          notUnique = false;
        }
    
      }).catch(function (err) {
        return response.send(500);
      });
    
    } while (notUnique);
    

    但只有我得到的是无限循环,notUnique 从不切换到true。以防万一,这是针对empy数据库进行测试的。

    我怎么能实现它?

2 个答案:

答案 0 :(得分:2)

您可以使用异步模块轻松完成此操作:

var async = require('async')

async.forever(
    function(next) {
        key = randomKey(8);

        Group.findOne({numberId: key}).then(function (foundGroup) {
          console.log("cb");

          if (! foundGroup) {
            console.log("not found")
            notUnique = false;
            next(new Error(), key) // break forever loop with empty error message and the key
          }
          else 
            return next() //continue loop

        }).catch(function (err) {
          next(err); //break loop
          return response.send(500);
        });
    },
    function(err, key) {
        if(key){
           newGroup.key = key;
        }

    }
);

答案 1 :(得分:1)

由于你已经在使用promises,我会做类似这样的事情:创建一个递归返回promise,创建一个promise链的函数,并在条件满足条件时最终抛出错误。然后你只需要抓住最后的错误。

修改:已更新以返回密钥

function find(){
    var key = randomKey(8);
    return Group.findOne({numberId: key })
    .then(function(foundGroup) {
        if(foundGroup) return find(); // recursion
        else throw key;
    }).catch(function(err){ // in case Group.findOne throws
        throw key; 
    });
}
find().catch(function(key){
    return response.send(key);
});

这里的find函数将继续递归调用,只要它一直找到一个有效的对象。由于它返回一个承诺,它们将自动链接。

如果并且最终找不到该对象,或者Group.findOne抛出错误,则会抛出该密钥。

find().catch将捕获最终错误,这将成为关键。