2015-06-26 173 views
0

对于Node API,我必须生成一个随机的字母数字键,这应该是唯一的,并且SHORT(我不能使用uuid或Mongo ObjectID)。如何使用Node.js处理while循环内的异步操作?

我觉得这样的逻辑:

  1. 生成密钥,
  2. 查询的MongoDB重点所有脑干
  3. 如果键存在,重复上述过程,
  4. 如果键不存在,其分配和回应客户。

我试过那么:

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数据库进行测试的。

我怎么能实现它?

+0

你能生成很多密钥来测试吗?如果是这样,您可以使用$ in操作符批量查询它们。你可能会发现比你生成的密钥更少的对象,然后你只需检查一个密钥是否存在,而对应的对象不存在。 – laggingreflex

回答

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

    } 
); 
+2

这可能是最实用的方法。仅供参考,有一个关于未来版本的Javascript(ECMAScript 7)的建议,称为异步/等待,可以让您更简洁地编写这个脚本,今天您可以使用它,感谢Babel:https://babeljs.io/docs/advanced /变压器/其他/异步到发电机/ –

1

既然你已经在使用的承诺,我会做这样的事情:创建一个递归返回一个承诺的功能,创建一个承诺链,并且当条件不满足时最终抛出错误。然后你只需要抓住最后的错误。

编辑:更新回到这里的关键

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将捕获最终的错误,这将是关键。