Почему NodeJS* событие l oop продолжается после моего обещания? - PullRequest
2 голосов
/ 28 апреля 2020

Вопрос

Как я могу получить NodeJS только для продолжения события l oop, пока все аргументы не будут проанализированы?

Информация

Исходя из этого и этого ответа, я получил Promise за работу, поэтому, когда --password используется в приложении, над которым я работаю. Теперь он ожидает ввода данных пользователем и сразу не продолжает событие NodeJS l oop.

if (argv.password || argv.w) {
  const p = new Promise((res) => {
    read({ prompt: 'Password: ', silent: true }, function(er, password) {
      console.log('Your password is: %s', password);
      res(password);
    })
  });
  p.then((pw) => console.log(pw));
}

Вышеописанное работает отлично, но когда я добавляю

if (argv.update || argv.u) {
  console.log('Not suppose to see this yet')
  cUpdate(argv.input, config, proj, argv.username, password)
}

затем также выполняет этот код, а это не то, что мне нужно.

Если я добавлю выше

if (argv.password || argv.w) {
  const p = new Promise((res) => {
    read({ prompt: 'Password: ', silent: true }, function(er, password) {

      // NEW CODE ADDED HERE
      if (argv.update || argv.u) {
        cUpdate(argv.input, config, proj, argv.username, password)
      }

      res(password);
    })
  });
  p.then((pw) => console.log(pw));
}

, тогда я получаю эту ошибку от cUpdate()

(node:9005) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:9005) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Причина этого в том, что где-то есть ошибка в обработчике, и я даже подозреваю, что обещание не в вашем коде, а скорее в том методе read, который вы вызываете.

Во избежание чтобы код обработчика обещаний был как можно более простым и как можно больше использовал цепочку из then:

if (argv.password || argv.w) {
  const p = new Promise((res) => {
    read({ prompt: 'Password: ', silent: true }, function(er, password) {
      res(password);
    })
  });
  p.then((password) => {
    console.log(password); 
    if (argv.update || argv.u)
      cUpdate(argv.input, config, proj, argv.username, password);
  });
}

Теперь я могу предположить, что метод cUpdate завершается неудачно (не похоже, это условие), поэтому нам нужна некоторая обработка ошибок - сначала в фактическом приглашении, а также вокруг cUpdate.

if (argv.password || argv.w) {
  const p = new Promise((res, rej) => {
    read({ prompt: 'Password: ', silent: true }, function(er, password) {
      if (er) rej(er);
      else res(password);
    })
  });

  p.then((password) => {
    console.log(password); 
    if (argv.update || argv.u)
      cUpdate(argv.input, config, proj, argv.username, password);
  })
  .catch(e => console.error(e));
}

Теперь вы, вероятно, увидите ошибку там, если она происходит, например, от пропущены записи config или proj.

Я бы также предположил, что ошибка может происходить из-за метода cUpdate и что она также может быть асинхронной, но поскольку вы не пытаетесь ловите ошибку где угодно, и вы не обрабатываете обещание, которое показывает предупреждение там. К счастью, метод then позволяет вам вернуть еще один Promise, и он также будет обработан. Я также упростил бы обработчик чтения, используя promisify, например:

const _read = require("util").promisify(read);

if (argv.password || argv.w) {
  _read({ prompt: 'Password: ', silent: true }) // this will essentially handle the error and resolve with the password
    .then(password => {
      console.log(password); 
      if (argv.update || argv.u)
        // all you need it to return the output of the method here if it's a promise.
        return cUpdate(argv.input, config, proj, argv.username, password);
    })
    .catch(e => {
      console.error(e);
      process.exit(10); // this will allow you to see an error in the command line
    });
}
1 голос
/ 28 апреля 2020

Вам необходимо обработать ваши ошибки:

Реализовать обработчик отклонения, если происходит ошибка.

if (argv.password || argv.w) {
      const p = new Promise((res, rej) => {
        read({ prompt: 'Password: ', silent: true }, function(er, password) {

          // NEW CODE ADDED HERE
          if (er) rej(er)
          if (argv.update || argv.u) {
            cUpdate(argv.input, config, proj, argv.username, password)
          }

          res(password);
        })
      });
      p.then((pw) => console.log(pw)).catch(err=> console.log(err))
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...