在脚本标签中使用 Promises 不起作用?

Using Promises in script tag not working?

我的以下代码用于使用承诺在 DOM 中附加脚本。 (以下所有代码都在 iframe 内执行,用于 A 帧技术,我的代码是使用 Google Blockly[基于块的编码] 生成的)

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');
      });
    }
  });

下面的脚本是我调用 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);

我的代码字符串 1 生成:(不起作用)

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();

我的代码字符串 2 生成:(有效)

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();

我生成的代码字符串 3:(仍然有效)

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();

每当我点击播放按钮时,callAppendScript(code) 就会被执行,当它执行时,

对于 代码字符串 1,它在 aframeWindow.onGreenPlayButtonClicked 中给出 undefined (不正确) 对于 code string 2,它给了我 onGreenPlayButtonClickedaframeWindow.onGreenPlayButtonClicked 的函数签名(正确)

那么,为什么它对案例 1 不起作用,我尝试了所有方法但无法弄清楚。我只发现对于 onGreenPlayButtonClicked 之外的任何 await 关键字,我得到 aframeWindow.onGreenPlayButtonClicked 位于 appendScript 函数内。

谢谢

appendScript 中没有任何内容等待 main() 调用 returns 的承诺。如果您正在异步初始化 onGreenPlayButtonClicked,它不会在附加脚本元素后立即可用。

我建议你试试

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");
}