繁体   English   中英

如何使用 async/await 从用户那里获取输入,但要等到整个条件语句被读取后再解析?

[英]How to use async/await to get input from user but wait till entire condition statement is read before resolving?

我创建了一个 function 提示用户输入 URL,然后验证输入的输入实际上是 URL。 The issue is, when I call this function from my other function, I have been able to get it to wait for user input before but it doesn't go through the entire condition statement before returning the url.

在 getURL() 中设置变量之前,如何使用 promises/async/await 等到我的 requestSiteURL() function 完成其条件语句?

const readline = require('readline').createInterface({
   input: process.stdin,
   output: process.stdout,
});

// request url from user in command prompt
const requestSiteURL = () => {
  return new Promise((resolve, reject) => {
    readline.question('Please type url: ', async (url) => {
      if (validUrl.isUri(url)) {
        readline.close();
        resolve(url);
        // if user types no, then use base url
      } else if ('No' || 'no' || 'NO') {
        url = URL;
        resolve(url);
      } else {
        reject(
          console.log(
            'Please type in a valid URL or type "no" to use base url.'
          )
        );
        requestSiteURL();
      }
    });
  });
};

// grabs all urls from original link and returns array
const getURLS = async () => {
  let url = await requestSiteURL();
  url = deleteFowardSlash(url);
  try {
    const res = await axios.get(url);
    const data = res.data;
    const $ = cheerio.load(data);

    const urlQueue = [];

    // finds all absolute links and pushs to urlQueue array
    $("a[href^='http']").each((i, elem) => {
      let link = $(elem).attr('href');
      //checks to make sure link isnt any duplicate links in urlqueue array
      link = deleteFowardSlash(link);
      uniqueLinkChecker(link, urlQueue);
    });
    return urlQueue;
  } catch (err) {
    console.error(err);
    return response.status(400).send(err);
  }
};

我认为这是语法问题。 在这里,我将原行切换为正确使用 Promise 构造函数。 Promise mdn

// request url from user in command prompt
const requestSiteURL = () => {
  return new Promise((resolve, reject) => {
    readline.question('Please type url: ', async (url) => {
      if (validUrl.isUri(url)) {
        readline.close();
        resolve(url);
        // if user types no, then use base url
      } else if (url.toLowerCase() === 'no') {
        url = URL;
        resolve(url);
      } else {
        console.log(
          'Please type in a valid URL or type "no" to use base url.'
        )
        requestSiteURL().then(resolve);
      }
    });
  });
};

编辑:添加异步/等待版本。 基本上我认为你不必拒绝。 我编辑了上面的内容也不要拒绝。 另外我假设URL是默认的 url (这与全局URL命名空间冲突,仅供记录)

// request url from user in command prompt
const requestSiteURL = async function () {
  const url = await new Promise(resolve => {
    readline.question('Please type url: ', resolve)
  })
  if (validUrl.isUri(url)) {
    readline.close()
    return url
  } else if (url.toLowerCase() === 'no') {
    return URL
  } else {
    console.log('Please type in a valid URL or type "no" to use base url.')
    return requestSiteURL()
  }
}

乍一看,您的“其他”条件似乎根本不会等待。 您拒绝 promise 并递归调用requestSiteURL() ,但对返回的 promise 不执行任何操作。 这将再次提出问题,但调用 function 无法访问该 promise。 退回的原件 promise 已经被拒收。 新的 promise 没有在任何地方引用,因此当第二次调用 resolve 或 reject 时,没有代码可以访问结果。

如果您希望您的代码失败并拒绝返回的 promise,那么您不应该在 else 语句中再次调用它。

如果您确实希望 function 一直问问题,直到输入有效答案,您可以通过将代码封装在 function 中来解决该问题,并在错误时继续调用它,直到它使用原始的“解决”参数解决promise 你退货。 似乎 readline.question() 也不需要异步 function :

// request url from user in command prompt
const requestSiteURL = () => {
  return new Promise((resolve, reject) => {
    const askQuestion = () => {
      readline.question('Please type url: ', (url) => {
        if (validUrl.isUri(url)) {
          readline.close(); // close readline here?
          resolve(url);
        } else if ('No' || 'no' || 'NO') {
          url = URL;
          // don't close readline here?
          resolve(url);
        } else {
          console.log(
            'Please type in a valid URL or type "no" to use base url.'
          );
          // call askQuestion() again until we resolve with something
          askQuestion()
        }
      });
      
      // call askQuestion() the first time
      askQuestion();
  });
};

暂无
暂无

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

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