Welcome Guest Search | Active Topics | Sign In | Register

Async/Await in Javascript Options
BenjaminSimpson1989
Posted: Tuesday, April 2, 2019 6:00:15 PM
Rank: Advanced Member
Groups: Member

Joined: 1/12/2015
Posts: 81
I would like to use await/async in the EvalScript but it's not working. Here's the code I'm trying:
Code: JavaScript
async function f(imageUrl) {
  let response = await fetch(imageUrl);
return 1;
}
await f('https://www.essentialobjects.com/Images/Logo.gif');


When I view the console in the application I see the error message:
Quote:
Uncaught SyntaxError: await is only valid in async function (index):5


But when I copy and paste and run the code directly in the console, it works fine.

Here's the real code I'm trying to run:
Code: JavaScript
await (async function() {
async function UrlToBase64(imageUrl) {
  async function getImageBlob(imageUrl) {
    const response = await fetch(imageUrl);
    return response.blob();
  }
  function getBase64(file) {
    const reader = new FileReader();
    return new Promise(resolve => {
      reader.onload = ev => {
        resolve(ev.target.result);
      }
      reader.readAsDataURL(file);
    });
  }

  var imageBlob = await getImageBlob(imageUrl);

  return await getBase64(imageBlob);
}
var p=await UrlToBase64($x('//img')[0].src);
return p;
})();


And I'm getting the following error in the console window:
Quote:
Uncaught ReferenceError: await is not defined
at <anonymous>:2:1
VM22:2


But when I copy and paste and run the code directly in the console, it works fine.
eo_support
Posted: Wednesday, April 3, 2019 10:45:51 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,218
Hi,

You won't be able to use async/await effectively with EvalScript because async function returns a Promise that is to be fulfilled or rejected later that can occur after EvalScript returns.

An easier way to understand await is to think an await split a single function into two functions. So the following function:

Code: JavaScript
async function f(imageUrl) 
{
  let response = await fetch(imageUrl);
  return 1;
}


In fact can be written this way:

Code: JavaScript
function OnDone()
{
  return 1;
}

function f(imageUrl)
{
    var promise = fetch(imageUrl);
    promise.OnDone = OnDone;
    return promise;
}


Note that the Promise object does not actually have an OnDone event. So the above code is only for demonstrating purpose.

Obviously calling f with EvalScript will return the promise object that you would not be able to do much about it. The key here is await does NOT wait. It simply yield the control and promise to resume at a later time.

When you enter code in Chrome's Developer Tools console, it would wrap your code into an anonymous function and then call that function. This is why when you type await directly in the script console it will take it but if you call WebView.EvalScript it won't take it because WebView.EvalScript does not automatically use an anonymous function around your script code.

Hope this helps.

Thanks!
BenjaminSimpson1989
Posted: Wednesday, April 3, 2019 11:08:48 AM
Rank: Advanced Member
Groups: Member

Joined: 1/12/2015
Posts: 81
So how would you suggest writing asynchronous Javascript code using the EvalScript that can be repeatedly checked for by .NET to see if the function completed?
eo_support
Posted: Wednesday, April 3, 2019 11:12:00 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,218
You just call back into .NET when you are done:

https://www.essentialobjects.com/doc/webbrowser/advanced/jsext.aspx

Forget about async/await --- they are just syntactic sugar.


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.