0xAnon
0xAnon

Reputation: 897

Using Promises in script tag not working?

My below code is used to append scripts in DOM using promises. (All below code executes inside iframe for A-frame technology and my code is being generated using Google Blockly[Block-based coding] )

export const appendScript = async({
      src,
      aframeWindow,
      code,
      id
    },
    doc,
    callback,
  ) =>
  new Promise(resolve => {
    const startDate = new Date();
    const script = doc.createElement('script');
    if (src) script.src = src;
    if (code) {
      script.text = code;
    }
    if (id) {
      script.id = id;
    }

    doc.head.appendChild(script);
    if (callback) callback();
    if (code) {
      if (callback) {
        callback();
      }
      console.log(aframeWindow.onGreenPlayButtonClicked, "===="); // undefined when code string contains await outside ongreenplaybuttonclicked fn
      resolve('resolved');
    } else {
      script.addEventListener('load', () => {
        const endDate = new Date();
        const seconds = (endDate.getTime() - startDate.getTime()) / 1000;
        console.log('script loaded: ', src, `took ${seconds} to load`);
        resolve('resolve2');
      });
    }
  });

The below script is my function that calls appendscript.

const callAppendScript = async code => {
  const CODE_VERSION = aframeWindow.CODE_VERSION;
  code = `
           async function main(inPlayMode) {
              let CURRENT_CODE_VERSION = CODE_VERSION;
              ${code};
            }
            main();
          `;


  let x = await appendScript({
      code,
      aframeWindow,
      id: 'code'
    },
    aframeWindow.document,
  );
}

callAppendScript(code);

My code string 1 that generates : (donot work)

async function main(inPlayMode) {
  let CURRENT_CODE_VERSION = !inPlayMode ? 0 : window.CODE_VERSION;
  var greeting;
  greeting = await HatchTranslateEngine.translate(`Hello`, 'en'); //async

  window.onGreenPlayButtonClicked = async function onGreenPlayButtonClicked() {
    await MinecraftAvatar.speakSound(greeting, true)

  };
}
main();

My code string 2 that generates : (works)

async function main(inPlayMode) {
  let CURRENT_CODE_VERSION = !inPlayMode ? 0 : window.CODE_VERSION;
  var greeting;
  greeting = Hatch.convert(`Hello`, 'jp'); //syncrhonous

  window.onGreenPlayButtonClicked = async function onGreenPlayButtonClicked() {
    await MinecraftAvatar.speakSound(greeting, true)

  };
}
main();

My code string 3 that generates: (still works)

async function main(inPlayMode) {
  let CURRENT_CODE_VERSION = !inPlayMode ? 0 : window.CODE_VERSION;
  var greeting;


  window.onGreenPlayButtonClicked = async function onGreenPlayButtonClicked() {
  greeting = await HatchTranslateEngine.translate(`Hello`, 'en'); //async this still works (inside playbtn)
    await MinecraftAvatar.speakSound(greeting, true)

  };
}
main();

Whenever i click play button, callAppendScript(code) gets executed , and when it does so,

For code string 1, it gives me undefined in aframeWindow.onGreenPlayButtonClicked (incorrect) For code string 2, it gives me function signature of onGreenPlayButtonClicked in aframeWindow.onGreenPlayButtonClicked (correct)

So, why is it not working for case 1 , I tried everything but could not figure it out. I only found out that for any await keyword that is outside onGreenPlayButtonClicked, I get aframeWindow.onGreenPlayButtonClicked which is inside appendScript function.

Thankyou

Upvotes: 0

Views: 600

Answers (1)

Bergi
Bergi

Reputation: 664297

Nothing in the appendScript waits for the promise that the main() call returns. If you are asynchronously initialising onGreenPlayButtonClicked, it won't be immediately available after appending the script element.

I would suggest you try

const callAppendScript = async code => {
  const CODE_VERSION = aframeWindow.CODE_VERSION;
  code = `
    async function main(inPlayMode) {
      let CURRENT_CODE_VERSION = CODE_VERSION;
      ${code};
    }
    // no main() call here
  `;
  await appendScript({
    code,
    aframeWindow,
    id: 'code'
  }, aframeWindow.document);

  console.log(aframeWindow.onGreenPlayButtonClicked, "before");
  await main();
//^^^^^^^^^^^^
  console.log(aframeWindow.onGreenPlayButtonClicked, "after");
}

Upvotes: 2

Related Questions