我关注了 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/