如何获得在函数中以正确顺序工作的承诺?

How do I get promises to work in the right order in a function?

提问人:elliot exists 提问时间:10/24/2023 更新时间:10/24/2023 访问量:45

问:

我正在尝试创建一个系统,为用户生成一个 radom ID 号,然后检查它是否已经在 mysql 数据库中。如果是,它将生成一个新的 ID 并与数据库进行检查。它将继续此操作,直到它生成一个唯一标识符并将其返回到函数外部。我对 JavaScript、Node 和异步函数很陌生,所以我真的不知道自己在做什么。

我试过使用promises,但是该函数总是只返回“undefined”,并且checkChatIdExists直到之后才完成。

generateId() 只返回一个 19 位字符串,con 是使用 MySQL2 建立的数据库连接

function checkChatIdExists(id) {
    return new Promise((resolve, reject) => {
        con.query("SELECT id FROM messages WHERE id = " + id, (err, result)=>{
            if(err !== null) { console.log(err) };
            if(result.length == 0) {
                resolve(id);  //newly generated id is okay
            } else {
                reject("ID was not Unique");         //newly generated id was not okay
            }
        })
    })
}

async function generateChatId() {
    
    async function generateAndCheckIdValid() {
        let id = await generateId();
        console.log("ID generated - " + id);
        checkChatIdExists(id).then((validId) => {
            return validId;       
        }).catch((message) => {
            console.log(message);
            return generateAndCheckIdValid();            //if id does exist then run again
        })
    }

    let id = await generateAndCheckIdValid();
    return id;
}
javascript 节点.js 异步 async-await node-mysql2

评论

2赞 Quentin 10/24/2023
generateAndCheckIdValid Only 在 catch 部分有一个 return 语句。
0赞 Pointy 10/24/2023
不要用于 ;用。.then()checkChatIdExists()await
0赞 Konrad 10/24/2023
更改为checkChatIdExists(id).then((validId) => {return checkChatIdExists(id).then((validId) => {
0赞 CherryDT 10/24/2023
旁注:mysql2 还支持 promise 包装器,请查看其文档。如果使用它,则可以将函数简化为 .另外,我假设可能来自用户 - 并且您没有受到 SQL 注入的保护!不要嵌入到查询中,而是使用参数: - 或使用 sql-template-strings: 。checkChatIdExistsif (await con.query(......)) { return id } else { throw new Error('ID was not unique') }ididcon.query('SELECT id FROM messages WHERE id = ?', [id])sql`SELECT id FROM messages WHERE id = ${id}`
0赞 CherryDT 10/24/2023
(先发制人地评论人们说“但模板字符串也很脆弱”:这不仅仅是一个普通的模板字符串!)

答:

1赞 Nicholas Tower 10/24/2023 #1
async function generateAndCheckIdValid() {
  const id = await generateId();
  console.log("ID generated - " + id);
  checkChatIdExists(id)
    .then((validId) => {
      return validId;
    })
    .catch((message) => {
      console.log(message);
      return generateAndCheckIdValid(); //if id does exist then run again
    });
}

这个异步函数中没有 return 语句,因此它的 promise 将隐式解析为 .回调中有一个 return 语句,但这不会做任何值得注意的事情。我建议你不要混用/搭配,只坚持一种风格。使用 / 代码将是:undefined.thenasyncawait.thenasyncawait

async function generateAndCheckIdValid() {
  let id = await generateId();
  console.log("ID generated - " + id);
  try {
    const validId = await checkChatIdExists(id);
    return validId;
    // If you prefer, the above 2 lines can be shortened to:
    // return await checkChatIdExists(id);
  } catch (message) {
    console.log(message);
    return generateAndCheckIdValid()
  }
}

如果您更喜欢使用 ,则可以编写如下代码:.then

function generateAndCheckIdValid() {
  return generateId() // <--- note the `return`
    .then(id => {
       console.log("ID generated - " + id);
       return checkChatIdExists(id);
    })
    // You don't need a .then which just re-returns the value. The promise
    //   is already resolving to that value
    // .then(validId => { return validId })
    .catch(message) => {
      console.log(message);
      return generateAndCheckIdValid();
    });
}

评论

0赞 elliot exists 10/25/2023
使用 .then 方法,当我运行它时,它返回的是 promise 对象而不是 ID。我如何从中获取有效身份证件?
0赞 Nicholas Tower 10/25/2023
要访问承诺的最终价值,请访问承诺或调用它。例如,或await.thenlet id = await generateAndCheckIdValid();generateAndCheckIdValid().then(id => { ... })