gpt4 book ai didi

javascript - 如何调用函数,但在有值之前不接收响应?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:47:38 25 4
gpt4 key购买 nike

我有一个查询 DOM 并返回数据属性数组的函数。

var getUIDs = function () {

$list = $('.foo');

if ( $list.length ) {

// loop through all the .foos and build an array
return fooArray;

} else {

setTimeout(function(){
getUIDs()
}, 500);

}

}

有时可以在 .foo 出现在 DOM 中之前调用此函数。这就是为什么如果我每半秒左右检查一次,数组将在几秒钟内存在并且我可以将其发回。

我的问题是,是否有一个我应该遵循的既定模式允许调用一个函数,但在有一个函数之前不会收到返回值?

最佳答案

MutationObserver

这是一个使用 MutationObserver 的演示 – 但它是非常裸机并且难以与之交互。如果我们想使用它,我们需要创建自己的函数来抽象掉一些复杂性

var target =
document.getElementById('main')

var observer =
new MutationObserver(muts =>
muts.forEach(m => console.log(m)))

observer.observe(target, {childList: true});

setTimeout(() => {
var span1 = document.createElement('span')
span1.textContent = 'cat'
target.appendChild(span1)
}, 1000)

// { Mutation }
<div id="main"></div>


MutationObserver 驯服到一个健全的 API 中

我们可以制作我们自己的 nextMutation 函数,它接受一个文档查询选择器并返回下一个添加的 child 的 Promise

const nextMutation = sel =>
new Promise((resolve,_) => {
const obs = new MutationObserver(muts => {
for (const {addedNodes} of muts)
if (addedNodes.length > 0) {
resolve(addedNodes[0])
obs.disconnect() // stop observing
return // stop iterating
}
})
obs.observe(document.querySelector(sel), {childList: true})
})


// demo mutation: add some element to #main in 1 second
setTimeout(() => {
var span1 = document.createElement('span')
span1.textContent = 'cat'
document.querySelector('#main').appendChild(span1)
}, 1000)

nextMutation('#main')
.then(child => console.log('added child', child)) // added child: <span>cat</span>
.catch(console.error)
<div id="main"></div>


等待太久超时

上面的 nextMutation 会无限期地等待,直到一个子节点被添加到目标中。如果在 X 秒内未添加子项,我们想报错怎么办?当然,我们可以扩充我们的 nextMutation 函数来做到这一点

此代码片段还演示了您可以将多个观察者附加到同一个目标。下面,一个元素在 domReady 后 1 秒添加到目标。最多等待 2 秒的观察者将成功捕获此突变——但是,只等待 0.5 秒的观察者将抛出错误,因为它没有观察到突变

const nextMutation = sel =>
new Promise((resolve, reject) => {
const obs = new MutationObserver(muts => {
for (const {addedNodes} of muts)
if (addedNodes.length > 0) {
resolve(addedNodes[0])
obs.disconnect()
return
}
})
obs.observe(document.querySelector(sel), {childList: true})
})

const awaitNextMutation = (sel, ms) =>
Promise.race([
nextMutation(sel),
new Promise((_,reject) =>
setTimeout(reject, ms, Error('awaitNextMutation timeout')))
])

// demo mutation: add some element to #main in 1 second
setTimeout(() => {
var span1 = document.createElement('span')
span1.textContent = 'cat'
document.querySelector('#main').appendChild(span1)
}, 1000)

// wait for up to 2 seconds; since the child is added within
// 1 second, this promise will resolve just fine
awaitNextMutation('#main', 2000)
.then(child => console.log('added child', child)) // added child: <span>cat</span>
.catch(console.error)

// this one only waits 500 ms so an Error will throw
awaitNextMutation('#main', 500)
.then(child => console.log('added child', child))
.catch(console.error) // => Error awaitNextMutation timeout
<div id="main"></div>

关于javascript - 如何调用函数,但在有值之前不接收响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44425267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com