Andy
Andy

Reputation: 8918

Using ES2017 async with jQuery .ready()

I'm learning about the async function feature introduced in ES2017, and I couldn't seem to get the following to work:

async function sayHelloAsync() {
  let {autosave} = await browser.storage.local.get('autosave');
  if (autosave) {
    $('#helloButton').click();
  }
}

$(sayHelloAsync);

I have managed a workaround for my needs in my small application, but I'm wondering why this would not work. As soon as I remove the async, it works as expected. I also have other custom event bindings which use async functions as callbacks, and they work just fine.

I am using Google Chrome 57 on Linux.

Update

I updated my code sample to remove the confusion about my need for loaded DOM and jQuery.

Upvotes: 3

Views: 3789

Answers (3)

Andrii Litvinov
Andrii Litvinov

Reputation: 13182

UPD: As Quentin mentioned, the issues was already fixed and jQuery 3.6.0 (and maybe few earlier versions) works as expected.

I have checked jQuery source code and here is a check it performs to find out what the argument is:

isFunction: function( obj ) {
  return jQuery.type( obj ) === "function";
}

And jQuery.type( obj ) returns object not function as expected. That's probably a bug in jQuery, but that's why the function is not executed.

Dug a bit more and jQuery calls toString.call( obj ) ti determine a type and tries map the result to known type. It cannot and that's why it returns object.

So the problem here is with jQuery not with your async function.

Upvotes: 5

Kyohei Kaneko
Kyohei Kaneko

Reputation: 1012

It seems the OP found an answer to their problem that isn't actually an answer to the question title. I wanted to await the document.ready function in a Puppeteer script I was writing that utilised jQuery.

So here's how I did it; which answers the question as titled:

You can wrap the document.ready function in a promise that resolves when the page is ready.

  //Wrap document ready function in a promise to be able to await it
  async domReady() {
    let promise = new Promise((resolve, reject) => {
      $(document).ready(() => {
        resolve("ready");
      });

      //Any reason for rejection could go here and have a call to reject(error);
    });

    return promise;
  }

Then if you want to wait for the document to load:

await domReady();
// The rest of your dependant code goes here...

Upvotes: 0

Asler
Asler

Reputation: 79

You can use native js

document.addEventListener( 'DOMContentLoaded',  async function () {});

Upvotes: 0

Related Questions