javascript - Promise 已解决,但代码在等待中停止

标签 javascript promise async-await

我关注了 Mozilla 的 docs 。我创建了一个内部带有 Promise 的函数。当选择器出现在页面上时,Promise 就会得到解决(如果没有,该函数会再次运行)。那么代码应该在 await 之后继续:

;(async () => {
  const titleSel = '.playbackSoundBadge__titleLink'
  document.querySelector(titleSel).click()
  const moreSel = 'button[title="More"]'
  await waitForEl(moreSel)
  console.log('after await')

  function waitForEl(selector) {
    return new Promise(resolve => {
      console.log(selector)
      if (document.querySelector(selector)) {
        console.log('resolved')
        resolve('resolved')
      } else {
        console.log('rejected')
        setTimeout(() => {
          waitForEl(selector)
        }, 100)
      }
    })
  }
})()

但奇怪的是,'resolved' 被记录下来。但是 await 之后的代码不会运行。换句话说,'after wait' 永远不会被记录。

这是为什么,如何解决?

最佳答案

But strangely, 'resolved' is logged.
...
Why is this

waitForEl 被“递归地”调用(它通过 setTimeout 安排自身的调用)。每次调用 waitForEl 都会创建一个 Promise,因此您正在创建多个 Promise。您在控制台中看到的“已解决”来自其中一个 promise 。您还应该看到一条或多条“拒绝”消息。

问题是“parent”/“top” promise 永远不会得到解决,因为这里没有对返回值执行任何操作:

waitForEl(selector)

该函数返回一个 Promise,但您没有用它做任何事情,因此永远不会解析调用该函数的 Promise。

一个简单的解决方案是

waitForEl(selector).then(resolve)

但这也意味着您正在递归地创建 promise 。看来没有必要这样做。只需在 Promise 中定义一个调用自身的简单函数即可:

 function waitForEl(selector) {
    return new Promise(resolve => {
      console.log(selector)
      (function check()
        if (document.querySelector(selector)) {
          console.log('resolved')
          resolve('resolved')
        } else {
          console.log('rejected')
          setTimeout(check, 100);
        }
      }());
    })
  }

您仍然应该添加一些条件,在一段时间后拒绝 promise ,这样它就不会永远调用 setTimeout

关于javascript - Promise 已解决,但代码在等待中停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59787364/

相关文章:

javascript - 用于获取用户输入并将其传递给批处理文件的 GUI

提交后javascript引擎处理代码

javascript - 使用 promise

node.js - Bluebird 的适当 promise

javascript - webpack 2 不能在 IE11 上运行?

C# Async Await,重构了一个非常简单的练习程序但是给出了不同的行为

Javascript 对象数据未返回正确的值

javascript - 如何告诉屏幕阅读器阅读切换元素

javascript - 使用流异步读取文件时如何同步处理每一行/缓冲区

c# - 异步/等待、自定义等待程序和垃圾收集器