Is Innerhtml Asynchronous

Is innerHTML asynchronous?

Setting innerHTML is synchronous, as are most changes you can make to the DOM. However, rendering the webpage is a different story.

(Remember, DOM stands for "Document Object Model". It's just a "model", a representation of data. What the user sees on their screen is a picture of how that model should look. So, changing the model doesn't instantaneously change the picture - it take some time to update.)

Running JavaScript and rendering the webpage actually happen separately. To put it simplistically, first all of the JavaScript on the page runs (from the event loop - check out this excellent video for more detail) and then after that the browser renders any changes to the webpage for the user to see. This is why "blocking" is such a big deal - running computationally intensive code prevents the browser from getting past the "run JS" step and into the "render the page" step, causing the page to freeze or stutter.

Chrome's pipeline looks like this:

Sample Image

As you can see, all of the JavaScript happens first. Then the page gets styled, laid out, painted, and composited - the "render". Not all of this pipeline will execute every frame. It depends on what page elements changed, if any, and how they need to be rerendered.

Note: alert() is also synchronous and executes during the JavaScript step, which is why the alert dialog appears before you see changes to the webpage.

You might now ask "Hold on, what exactly gets run in that 'JavaScript' step in the pipeline? Does all my code run 60 times per second?" The answer is "no", and it goes back to how the JS event loop works. JS code only runs if it's in the stack - from things like event listeners, timeouts, whatever. See previous video (really).

https://developers.google.com/web/fundamentals/performance/rendering/

Getting innerHTML from 3 URLs - Asynchronous Problems

There are two issues:

  1. promise is a async, so you'll need get your variables within it's callback function
  2. chPageOne is a string, not element object.

Fixing these issues:

var chNumber = "11885705";
var chPageOne;
var chPageTwo;
var chPageThree;

const urls = [
'https://find-and-update.company-information.service.gov.uk/company/' + chNumber,
'https://find-and-update.company-information.service.gov.uk/company/' + chNumber + '/officers',
'https://find-and-update.company-information.service.gov.uk/company/' + chNumber + '/persons-with-significant-control'
];

// map every url to the promise of the fetch
// let requests = urls.map(url => fetch(url)); //don't need this

// Promise.all waits until all jobs are resolved
Promise.all(urls.map(url => fetch(url)
.then(r => r.text())
.catch(err => console.error(err))))
.then(results => {

// Initialize the DOM parser
var parser = new DOMParser();

// Parse the text
var doc1 = parser.parseFromString(results[0], "text/html");
var doc2 = parser.parseFromString(results[1], "text/html");
var doc3 = parser.parseFromString(results[2], "text/html");

// You can now even select part of that html as you would in the regular DOM
// Example:

chPageOne = doc1.getElementById('content-container');
chPageTwo = doc2.getElementById('content-container');
chPageThree = doc3.getElementById('content-container');

document.getElementById('holdingAreaOne').innerHTML = chPageOne.innerHTML;
document.getElementById('holdingAreaTwo').innerHTML = chPageTwo.innerHTML;
document.getElementById('holdingAreaThree').innerHTML = chPageThree.innerHTML;

var companyName = chPageOne.getElementsByClassName("heading-xlarge")[0].innerText;
console.log(companyName)
//console.log(chPageOne);
//console.log(chPageTwo);
//console.log(chPageThree);

})
.catch(err => console.error(err))

execute .innerHTML in a function

You could try to use setTimeout.

Using a Function

I made this function which makes it easy to supply an array of objects you want to update.

/* 
timed_elemet_updates(array, int)
`elements` should be an array of objects which contains the
ID and HTML you want to update.
*/
function timed_element_updates(elements, seconds) {
var element = elements.shift();
document.getElementById(element.id).innerHTML = element.html;
setTimeout(timed_element_updates, (seconds * 1000), elements, seconds);
}

Sample usage:

function start() {
var elements = [
{id: '1a', html: 'bla'},
{id: '2b', html: 'blabla'},
{id: '3c', html: 'blablabla'},
];
timed_element_updates(elements, 1);
}
start();

This answer is more concise (less repeating lines of code), easier to use (just add more elements to the array), and more reusable (no new function for every element)

Original Answer

function one() {
document.getElementById("1a").innerHTML = "bla";
setTimeout(two, 1000);
}

function two() {
document.getElementById("2b").innerHTML = "blabla";
setTimeout(three, 1000);
}

function three() {
document.getElementById("3c").innerHTML = "blablabla";
}

one();

This will call function one(), then it will call two() after 1000 milliseconds (1 second), then it will call three() after 1000 milliseconds (1 second).

Async function and await keyword

Inside js1.js the function execute a promise that is asynchronous and you want it to wait for the Promise's result :

document.getElementById("app3").innerHTML = await myPromise;

At this point, the function will stop and wait for the "myPromise" to complete (resolve or reject).
More on : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/await

The function inside js2.js do not executes code that block it's execution, myDisplay2 can be executed in a synchrone way, the result of the promise will be executed later (if the promise resolve) in the :

.then(function (resp) { document.getElementById("app1").innerHTML = resp; });

To make it short, as soon as you are using "await" the function is "async".

why are ajax asynchronous calls not changing the innerHTML of elements?

You need to set a handler for when the async call completes, and do your DOM updates there:

function change() {
var ajax = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
var changeME = document.getElementById('changeMe');
changeME.innerHTML = ajax.responseText;
}
}
ajax.open('GET', 'data.txt', true);
ajax.send();
}

How to detect when innerHTML is complete

There is no need for such a function. Assigning to innerHTML will do so immediately before continuing to run any scripts.

If you really need to delay execution (say to allow the browser to redraw), use setTimeout with a delay of 1 (or other short interval).



Related Topics



Leave a reply



Submit