簡體   English   中英

為什么 NodeJS* 事件循環在我的 Promise 之后繼續?

[英]Why does NodeJS* event loop continues after my Promise?

問題

如何讓 NodeJS 只繼續事件循環,直到所有 arguments 都被解析?

信息

基於這個這個答案,我得到了Promise來工作,所以當我正在開發的應用程序中使用--password時。 現在它等待用戶輸入並且不會立即繼續 NodeJS 事件循環。

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.

您需要處理錯誤:

如果發生錯誤,請實施拒絕處理程序。

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

原因是處理程序中的某個地方出現錯誤,我什至懷疑 promise 不在您的代碼中,而是在您調用的read方法中。

為了避免這種情況,請讓您的 promise 處理程序代碼盡可能簡單,並盡可能使用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));
}

現在,如果錯誤來自例如缺少的configproj條目,您可能會在那里看到錯誤。

我還假設錯誤可能來自cUpdate方法內部並且它也可能是異步的,但是由於您沒有嘗試在任何地方捕獲錯誤並且您不處理 promise 它在那里顯示警告。 幸運的是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
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM