简体   繁体   中英

how to make an asynchronous javascript function synchronous

Given a button and it's click action set to be (in alpinejs )

<button x-on:click.prevent|debounce.3s="response = run();" type="button">Run</button>

when the run() function is defined like this:

function run() {
  // captcha();
  let data = input();
  data = confirm(data);
...
  data = request(url, data);
  return data;
}

It is a synchronous function and it works nicely.

The recaptcha documentation ( https://developers.google.com/recaptcha/docs/v3 ) states that if the button click is to be protected with recaptcha, it has to look like:

async function captcha() {
  let resp;
  grecaptcha.ready(function() {
    grecaptcha.execute(recaptcha_site_key, {action: 'run'}).then(function(token) {
        console.log(token);
        resp = run();
    });
  });
  return resp;
}

If the click action is set to be:

<button x-on:click.prevent|debounce.3s="response = await captcha();" type="button">Run</button>

It results to this error:

在此处输入图像描述

Can you please advise what I am doing wrong?

EDIT: added the return statement in the captcha function

for others that will be in the same situation as I am, here is the solution.

first step, I made the captcha function to return a promise

function captcha() {
    return new Promise(function(resolve, reject) {
      grecaptcha.ready(function() {
        grecaptcha.execute(recaptcha_site_key, {action: 'run'}).then(function(token) {
          resolve(token);
        });
      });
    });
}

second step, async/await for the variable to become available

async function run() {
  let g_recaptcha_response = await captcha();
  document.forms['params'].elements['g_recaptcha_response'].value = g_recaptcha_response;
  let data = input();
  data = confirm(data);
  if (data['error'] === true) {
    return data;
  }
  let url = `${origin}/app/json`;
  data = request(url, data);
  // note: preparing for input / next request.
  document.forms['params'].elements['token_id'].value = data['token_id'];
  return data;
}

third step, create an IIFE at the top-level

(async function(){ let response = await run(); })();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM