ETA 24 এপ্রিল 17
আমি কিছু async
/ এর সাহায্যে এটিকে কিছুটা সহজ করতে চেয়েছিলামawait
যাদুতে এটি , কারণ এটি এটিকে অনেক বেশি সংহত করে তোলে:
একই প্রতিশ্রুতিবদ্ধ-পর্যবেক্ষণযোগ্য ব্যবহার করে:
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 জিনিস ব্যবহার করতে হবে, সুতরাং সামঞ্জস্যতার বিষয়ে সচেতন হতে হবে (যেমন, আপনার শ্রোতা যদি বেশিরভাগ ক্ষেত্রে আমিশ, লুডাইট বা খারাপ, আই 88 ব্যবহারকারী হন)
প্রথমত, আমরা একটি পর্যবেক্ষক অবজেক্ট তৈরি করতে মিউটেশনউসারভার এপিআই ব্যবহার করব । আমরা এই বস্তুকে একটি প্রতিশ্রুতিতে resolve()
আবদ্ধ করব, এবং কলব্যাকটি বহিস্কার হওয়ার পরে (এইচ / টি ডেভিডওয়ালশব্লগ) ডেভিড ওয়ালশ ব্লগ নিবন্ধে মিউটেশনগুলি :
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")
}
জেনারেটর সম্পর্কে একটি জটিল অংশ হ'ল তারা কোনও সাধারণ ফাংশনের মতো 'রিটার্ন' করে না। সুতরাং, আমরা নিয়মিত ফাংশনের মতো জেনারেটর ব্যবহার করতে সক্ষম হতে একটি সহায়ক ফাংশন ব্যবহার করব। (আবার, hw / to 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 রূপান্তর একীভূত করতে পারেন। কি যে বিস্ময়কর।