การทางพิเศษแห่งประเทศไทย 24 เมษายน 17
ฉันต้องการที่จะลดความซับซ้อนเล็กน้อยด้วยเวทมนตร์async
/ await
เพราะมันทำให้รวบรัดมากขึ้น:
ใช้ promisified-observable เดียวกัน:
const startObservable = (domNode) => {
var targetNode = domNode;
var observerConfig = {
attributes: true,
childList: true,
characterData: true
};
return new Promise((resolve) => {
var observer = new MutationObserver(function (mutations) {
// For the sake of...observation...let's output the mutation to console to see how this all works
mutations.forEach(function (mutation) {
console.log(mutation.type);
});
resolve(mutations)
});
observer.observe(targetNode, observerConfig);
})
}
ฟังก์ชั่นการโทรของคุณสามารถทำได้ง่ายเพียง:
const waitForMutation = async () => {
const button = document.querySelector('.some-button')
if (button !== null) button.click()
try {
const results = await startObservable(someDomNode)
return results
} catch (err) {
console.error(err)
}
}
หากคุณต้องการเพิ่มการหมดเวลาคุณสามารถใช้Promise.race
รูปแบบง่าย ๆดังที่แสดงไว้ที่นี่ :
const waitForMutation = async (timeout = 5000 /*in ms*/) => {
const button = document.querySelector('.some-button')
if (button !== null) button.click()
try {
const results = await Promise.race([
startObservable(someDomNode),
// this will throw after the timeout, skipping
// the return & going to the catch block
new Promise((resolve, reject) => setTimeout(
reject,
timeout,
new Error('timed out waiting for mutation')
)
])
return results
} catch (err) {
console.error(err)
}
}
เป็นต้นฉบับ
คุณสามารถทำได้โดยไม่ต้องใช้ไลบรารี แต่คุณต้องใช้ ES6 บางอย่างดังนั้นควรรับรู้ถึงปัญหาความเข้ากันได้ (เช่นหากผู้ชมของคุณส่วนใหญ่เป็น Amish, luddite หรือแย่กว่านั้นคือผู้ใช้ IE8)
อันดับแรกเราจะใช้MutationObserver APIเพื่อสร้างวัตถุผู้สังเกตการณ์ เราจะห่อวัตถุนี้ไว้ในสัญญาและresolve()
เมื่อมีการโทรกลับ (h / t davidwalshblog) david walsh บทความบล็อกเกี่ยวกับการกลายพันธุ์ :
const startObservable = (domNode) => {
var targetNode = domNode;
var observerConfig = {
attributes: true,
childList: true,
characterData: true
};
return new Promise((resolve) => {
var observer = new MutationObserver(function (mutations) {
// For the sake of...observation...let's output the mutation to console to see how this all works
mutations.forEach(function (mutation) {
console.log(mutation.type);
});
resolve(mutations)
});
observer.observe(targetNode, observerConfig);
})
}
generator function
จากนั้นเราจะสร้าง หากคุณยังไม่ได้ใช้สิ่งเหล่านี้แสดงว่าคุณขาดหายไป แต่บทสรุปโดยย่อคือมันทำงานเหมือนฟังก์ชั่นซิงค์และเมื่อพบyield <Promise>
นิพจน์มันจะรอโดยไม่มีการปิดกั้นเพื่อให้สัญญา สำเร็จแล้ว ( เครื่องกำเนิดไฟฟ้าทำมากกว่านี้ แต่นี่คือสิ่งที่เราสนใจที่นี่ )
// we'll declare our DOM node here, too
let targ = document.querySelector('#domNodeToWatch')
function* getMutation() {
console.log("Starting")
var mutations = yield startObservable(targ)
console.log("done")
}
ส่วนที่ยุ่งยากเกี่ยวกับเครื่องกำเนิดไฟฟ้าคือพวกมันไม่ 'คืน' เหมือนฟังก์ชั่นปกติ ดังนั้นเราจะใช้ฟังก์ชันตัวช่วยเพื่อให้สามารถใช้ตัวสร้างเช่นฟังก์ชันทั่วไป (อีกครั้งh / t ถึง dwb )
function runGenerator(g) {
var it = g(), ret;
// asynchronously iterate over generator
(function iterate(val){
ret = it.next( val );
if (!ret.done) {
// poor man's "is it a promise?" test
if ("then" in ret.value) {
// wait on the promise
ret.value.then( iterate );
}
// immediate value: just send right back in
else {
// avoid synchronous recursion
setTimeout( function(){
iterate( ret.value );
}, 0 );
}
}
})();
}
จากนั้นที่จุดใดก่อนที่จะมีการกลายพันธุ์ DOM runGenerator(getMutation)
คาดว่าอาจจะเกิดขึ้นเรียกเพียง
ตอนนี้คุณสามารถรวมการกลายพันธุ์ของ DOM ในโฟลว์การควบคุมแบบซิงโครนัส การแข่งขันนั้นเป็นอย่างไร