如何解决在脚本标记中使用Promises无效?
我下面的代码用于使用promise在DOM中附加脚本。 (以下所有代码均在Aframe技术的iframe中执行,而我的代码是使用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');
});
}
});
下面的脚本是我调用附录的函数。
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,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
中给了我未定义(不正确)
对于 代码字符串2 ,它为我提供了aframeWindow.onGreenPlayButtonClicked
中onGreenPlayButtonClicked 的功能签名(正确)
所以,为什么它对情况1不起作用,我尝试了一切,但没有弄清楚。我只发现对于onGreenPlayButtonClicked之外的任何await
关键字,我都会得到aframeWindow.onGreenPlayButtonClicked
函数内部的appendScript
。
谢谢
解决方法
appendScript
中的任何内容都不会等待main()
调用返回的承诺。如果您要异步初始化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");
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。