繁体   English   中英

如何在Node.js的while循环中处理异步操作?

[英]How to handle async operations inside a while loop with Node.js?

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

我认为这种逻辑:

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

我该如何实现?

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

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

    }
);

由于您已经在使用诺言,因此我将执行以下操作:创建一个函数,该函数以递归方式返回诺言,创建诺言链,并在满足/不满足条件时最终引发错误。 然后,您只需要捕获该最终错误即可。

编辑 :更新以返回密钥

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM