Mongoose и NodeJS: создание уникального системного имени пользователя

1

Я хочу, чтобы создать уникальное имя пользователя, сгенерированное системой. Однако асинхронный характер функции findOne mongoose отключает меня.

У меня есть функция generateUniqueAccountName, которая принимает предложенное имя пользователя и проверяет с MongoDB, если предлагаемое имя пользователя уникально. Если он не уникален, то новое имя создается до тех пор, пока не будет найдено уникальное имя пользователя.

Звучит достаточно просто, но generateUniqueAccountName завершается еще до того, как будет найдено уникальное имя. Я попытался использовать Q (моя реализация здесь не показана), но не могла заставить ее работать.

Поблагодарили бы за любую помощь. Спасибо!

Это функция generateUniqueAccountName:

 /**
 * Returns a unique account name based on proposed name
 * @param {String} proposedName
 * @return {Promise}
 */
function generateUniqueAccountName(proposedName) {

  return Account.findOne({accountName: proposedName})
      .then(function(account) {
        if (account != null) {
          console.log('no can do try again: ' + proposedName);
          proposedName += Math.floor((Math.random() * 100) + 1);
          generateUniqueAccountName(proposedName);
        } else {
          console.log('proposed name is unique' + proposedName);
        }
        return proposedName;
      })
      .catch(function(err) {
        console.error(err);
        throw err;
      });
 }

generateUniqueAccountName вызывается так:

.then(function(newAccount) {
   // Next generate a unique account name
   console.log('Generating unique account name ...');
   let proposedName = (accounts[i].acctFName + accounts[i].acctLName)
                         .replace(/\s/g, '');

   return generateUniqueAccountName(proposedName.toLowerCase())
            .then(function(accountName) {
               console.log('the unique name is ' + accountName);
               newAccount.accountName = accountName;
               return newAccount;
             })
            .catch(function(err) {
               throw err;
             });
})
.then(saving_part);

Это примерный результат:

Generating unique account name ...
no can do try again: teylim
no can do try again: michaelalee
no can do try again: joeykwa
the unique name is teylim86
the unique name is michaelalee72
the unique name is joeykwa91
no can do try again: trishalee
the unique name is trishalee7
proposed name: michaelalee72 is unique
proposed name: joeykwa91 is unique
no can do try again: teylim86
no can do try again: trishalee7
proposed name: teylim8641 is unique
proposed name: trishalee734 is unique
Saving account trishalee7

Глядя на trishalee, как вы можете видеть, система пытается сохранить имя пользователя trishalee7, хотя, поскольку журнал показал, что trishalee7 не является уникальным именем

Теги:
mongoose
asynchronous
promise

1 ответ

3
Лучший ответ

Все, что вам нужно сделать, это добавить оператор return перед generateUniqueAccountName(proposedName):

function generateUniqueAccountName(proposedName) {
  return Account
    .findOne({accountName: proposedName})
    .then(function(account) {
      if (account) {
        console.log('no can do try again: ' + proposedName);
        proposedName += Math.floor((Math.random() * 100) + 1);
        return generateUniqueAccountName(proposedName); // <== return statement here
      }
      console.log('proposed name is unique' + proposedName);
      return proposedName;
    })
    .catch(function(err) {
      console.error(err);
      throw err;
    });
}
  • 0
    Ух ты! Это был быстрый ответ и, что более важно, решил проблему! Спасибо @alexmac.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню