Reputation: 171
I have a forEach
loop that processes data in an array. Somewhere in the middle of that loop I have to wait for a change in a DOM element, grab that change, process it, and only then can I continue processing the array.
I'm hoping to see this in console:
Preparing "aaa"
Waiting for result on "aaa"
Processing result on "aaa": <random number>
Got result for "aaa": <random number>something`
And the same thing for each element in stuffToProcess
array in the code snippet below. It's a simplified example of the code.
I realize similar questions have been asked and answered countless times before, but after reading through many of them, and trying many different things for hours, I still can't figure this one out.
function dummy() {
$('#trackMe').text(Math.random());
}
async function doWork(stuffToProcess) {
let target = $('#trackMe')[0];
let config = { attributes: true, childList: true, characterData: true, values: true };
let observer = new MutationObserver(function(mutations,item) {
console.log('Processing result on "%s": %s', item, target.innerText);
item = item + 'something';
return new Promise(resolve => {
resolve(item);
});
});
observer.observe(target, config);
stuffToProcess.forEach(async function(item) {
console.log('Preparing "%s"', item);
console.log('Waiting for result on "%s"', item);
let change = await observer(item);
//^^^ this needs to "await" for data from observer before the loop continues
console.log('Got result for "%s": %s', item, change);
});
//observer.disconnect();
}
doWork(['aaa', 'bbb', 'ccc']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="trackMe">No changes yet</p>
<button onclick="dummy()">Click me to change</button>
Upvotes: 4
Views: 4068
Reputation: 1
Here is an example using only JavaScript, I hope it helps you.
function getData() {
return new Promise(function(resolve, reject) {
// resolve();
// reject();
});
}
function example1() {
// code ...
async function getAsyncData() {
let data = await getData();
console.log(data);
// code ...
}
let element = document.getElementById(...);
let observer = new MutationObserver(function(mutations) {
getAsyncData();
});
let config = {attributes: true, childList: true, characterData: true};
observer.observe(element, config);
// code ...
}
Upvotes: -1
Reputation: 171
Well, I managed to solve it somehow. Probably not the cleanest solution though, so if anyone recommends any improvements on this, I'll happily edit the solution / upvote your answer.
function dummy() {
$('#trackMe').text(Math.random());
}
async function doWork(stuffToProcess) {
let target = $('#trackMe')[0];
let config = {
attributes: true,
childList: true,
characterData: true,
values: true
};
let observer;
function isItDone(item) {
return new Promise(resolve => {
observer = new MutationObserver(function(mutations) {
console.log('Processing result on "%s": %s', item, target.innerText);
result = target.innerText + 'something';
resolve(result);
});
observer.observe(target, config);
});
}
for (index in stuffToProcess) {
console.log('Preparing "%s"', stuffToProcess[index]);
console.log('Waiting for result on "%s"', stuffToProcess[index]);
let change = await isItDone(stuffToProcess[index]);
observer.disconnect();
console.log('Got result for "%s": %s', stuffToProcess[index], change);
}
}
doWork(['aaa', 'bbb', 'ccc']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="trackMe">No changes yet</p>
<button onclick="dummy()">Click me to change</button>
Upvotes: 3