Is the risk of using deprecated synchronous calls on the main thread worth it in JavaScript?

I have created a single page web application that relies on modifying a section of the page and then calling specific functions to format this section after it has been modified. One of the crucial post-modification calls I need to make is MathJax.

However, due to the asynchronous nature of Ajax, there are times when I don't get the desired effect as the scripts run before the contents of the page are fully ready. To address this issue, I have been using XMLHttpRequest().open() with "false" to make the requests synchronous and ensure that the page contents are fully loaded before executing the scripts.

Although this approach provides the desired behavior, it triggers a warning message stating: "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects on the end user’s experience."

While I prefer not to rely on deprecated features that may break in future updates, the current solution meets my requirements. However, I am concerned about the warning and if it might be disabled in upcoming web updates. In such a scenario, what alternatives should I consider?

EDIT: JS code:

function changeSection(section, page, button, sync=true)
{
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      $(section).empty();
      $(section).append(this.responseText);

      clearButtons();
      setButton(button);
    }
  };
  xhttp.open("GET", page, sync);
  xhttp.send();
}

function setLagrange() {
  path = MathLog_path + "modelling/lagrange_interpolation.html";

  changeSection("#VolatileSection", path, "lagrange_button", false);

  $('pre code').each(function(i, block) {
    hljs.highlightBlock(block);
  });
  MathJax.Hub.Config({
    tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
  });
  MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}

Answer №1

Is this warning something I should be worried about?

Definitely. :-) The warning is there for a reason - it will have a negative impact on the user experience.

What alternative approach should I take instead?

You can continue using asynchronous ajax and ensure to call the necessary functions from the completion handler.

If you are using XHR:

const xhr = new XMLHttpRequest();
xhr.addEventListener("load", () => {
    // Call your desired functions here
});
xhr.addEventListener("error", () => {
    // Handle any errors here
});
xhr.open("GET", "/path/to/the/resource");
xhr.send();

Alternatively, consider using fetch:

fetch("/path/to/the/resource")
.then(response => {
    if (!response.ok) {
        throw new Error("HTTP error " + response.status);
    }
    return response.appropriateMethodToReadBodyHere();
})
.then(data => {
    // Call your functions here
})
.catch(error => {
    // Handle errors here
});

You could also utilize an async function:

try {
    const response = await fetch("/path/to/the/resource");
    if (!response.ok) {
        throw new Error("HTTP error " + response.status);
    }
    const data = await response.appropriateMethodToReadBodyHere();
    // Call your functions here
} catch (error) {
    // Handle errors here
}

A piece of code has been modified. Here's an example with minimal changes:

function changeSection(section, page, button, sync=true, callback = () => {})
// *** ------------------------------------------------^^^^^^^^^^^^^^^^^^^^^
{
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      $(section).empty();
      $(section).append(this.responseText);

      clearButtons();
      setButton(button);
      callback(); // ***
    }
  };
  xhttp.open("GET", page, sync);
  xhttp.send();
}

function setLagrange() {
  path = MathLog_path + "modelling/lagrange_interpolation.html";

  changeSection("#VolatileSection", path, "lagrange_button", false, () => {
  // *** ---------------------------------------------------------^^^^^^^^^
      $('pre code').each(function(i, block) {
        hljs.highlightBlock(block);
      });
      MathJax.Hub.Config({
        tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
      });
      MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
  });
//^^^ ***
}

...considering ES2015+ features, utilizing fetch and returning a promise from changeSection would be preferable:

function changeSection(section, page, button, sync=true)
{
  return fetch(page)
    .then(response => {
      if (!response.ok) {
          throw new Error("HTTP error " + response.status);
      }
      return response.text(); 
    })
    .then(() => {
      $(section).empty();
      $(section).append(this.responseText);

      clearButtons();
      setButton(button);
    });
}

function setLagrange() {
  path = MathLog_path + "modelling/lagrange_interpolation.html";

  changeSection("#VolatileSection", path, "lagrange_button", false).then(() => {
  // *** ----------------------------------------------------------^^^^^^
      $('pre code').each(function(i, block) {
        hljs.highlightBlock(block);
      });
      MathJax.Hub.Config({
        tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
      });
      MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
  });
}

or by using async functions:

async function changeSection(section, page, button, sync=true)
{
  const response = await fetch(page);
  if (!response.ok) {
      throw new Error("HTTP error " + response.status);
  }
  await response.text(); 
  $(section).empty();
  $(section).append(this.responseText);

  clearButtons();
  setButton(button);
}

async function setLagrange() {
  path = MathLog_path + "modelling/lagrange_interpolation.html";

  await changeSection("#VolatileSection", path, "lagrange_button", false);
  $('pre code').each(function(i, block) {
    hljs.highlightBlock(block);
  });
  MathJax.Hub.Config({
    tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
  });
  MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}

Remember that setLagrange needs to be called from within an async function or its promise must be handled explicitly:

setLagrange(/*...*/)
.catch(error => {
    // Handle any errors
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Passing the contents of a datatable as parameters to a PHP script

I am facing a challenge with my datatable that has two columns, "Name" and "Age". After populating the datatable using Ajax, I create a button for each row. The goal is to send the "Name" and "Age" fields of the clicked row to a PHP script, which will then ...

Securing Credit Card Numbers with Masked Input in Ionic 3

After testing out 3-4 npm modules, I encountered issues with each one when trying to mask my ion-input for Credit Card numbers into groups of 4. Every module had its own errors that prevented me from achieving the desired masking result. I am looking for ...

Instructions on how to dynamically update a form field based on the input in another field using conditional statements

I'm seeking advice on how to automatically update a field based on user input without the need for manual saving. For example, if the user types '95' in the input field, the equivalent value displayed should be '1.0' in real-time. ...

Tips for formatting angular text sections

Within the scope of a controller, I have a status variable. After a successful rest PUT request, I add a message to this JavaScript variable. This message is displayed in my template using the {{status}} Is there a way to customize the styling of this mes ...

Include form data into an array of objects within an Angular data source

I am struggling to add the edited form data from edit-customers-dialog.ts into an array of objects in my datasource. The form.data.value is returning correctly, but I'm facing issues with inserting it properly into the array. As a beginner in Angular ...

Unusual layout in Next.js editor (VS Code)

My chosen formatter is prettier, but I'm encountering an issue with the way it handles simple JSX functions. Initially, my code looks like this: function HomePage() { return; <div> <h1>Hello Next.js</h1> <p> Welcome ...

Encountering an error in React Native: Unable to access property 'length' as it is

Currently, I am working on developing a registration application and I have encountered some issues in the final phases when attempting to submit the new data to the server. Below is the script I am using: import React from 'react'; import React ...

Tips for utilizing $.get information to update specific elements on a web page

I am currently utilizing jQuery 1.4.2 to smoothly navigate between similar web pages within Firefox 3. Upon clicking a link, a JavaScript script should load the new HTML, filter out the correct elements and replace them on the existing page. It appears th ...

Gain access to a variable within an AngularJS directive's scope

I am facing an issue with the following directive var chartDir = function () { return { scope: { stat: '=' }, link: function (scope, element, attr) { console.log(scope); return; } } HTML < ...

Order of execution for Angular 2 components

import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms'; import {Router, ActivatedRoute, Params} from '@angular/router'; import { Country } from &ap ...

Utilizing External Libraries in SAPUI5 Extension Development

I am facing an issue while trying to integrate an external library into my UI5 project. Specifically, I am working with jsPDF but it could be any other library as well. I have included it in the manifest.json file in the following manner: "js": [{ ...

When integrating Stripe into my Next.js application, I encounter a build error

I encountered an error when building my Next.js app with Stripe integration using "yarn build". However, when running the app locally with "yarn dev", it works perfectly without any errors. I'm struggling to figure out why this discrepancy is happeni ...

Encountering 'Illegal Invocation' error while running a basic script

Exploring the Speech Recognition API has been on my to-do list, so I decided to create a simple page that initiates recognition when clicking on the body element. Here is a snippet from my scripts.js file: var recognition = new window.webkitSpeechRecognit ...

Console output shows that the function results in undefined

When I pass a string parameter to a function, I expect the console to display "reff", but it is showing "undefined" instead. Here is the code snippet: var _ref; function foo(_ref='reff') { var bar = _ref.bar; return console.log(bar); } foo ...

Updating an object property within an array in Angular Typescript does not reflect changes in the view

I am currently delving into Typescript and Angular, and I have encountered an issue where my view does not update when I try to modify a value in an array that is assigned to an object I defined. I have a feeling that it might be related to the context b ...

Tips on scrolling the web page until the desired web element is visible and carrying out necessary tasks

When searching for input, multiple table data is retrieved. A "show as text link" is present in different table rows that needs to be clicked. I wrote a code that works fine in IE on one machine but does not work on a different machine due to variations i ...

Retrieve and send updated session variables via an Ajax call in Django while the page is still loading

Exploring my current progress and goals: On my Django website, users input data into a form that triggers a complex background process in the background_process view function. To ensure multiple users can access the website without variable conflicts duri ...

React Material UI - DataGrid Continuously Distracting Focus Away from Input Field

I'm currently facing an issue with my React web app using Material-UI. The problem arises when I try to type in the search input field, but the focus keeps getting stolen by the Material-UI DataGrid whenever I click on it. Oddly enough, this only occu ...

Avoid TypeError: cannot read property '0' of undefined in a Vue.js/Django project

I am currently working on a Django/Vue.js application. Upon submitting the login form, the Django view redirects to the user's username page, where the Vue.Js file retrieves data from the server. Below is the code snippet: async created(){ await ...

Encountering difficulty importing TypeScript files dynamically within a Deno executable

When attempting to import a file from aws in an exe using its public link based on user input, I am facing difficulties For example, I generated my exe with the command below deno compile --allow-all main.ts Users execute this exe using commands like ./e ...