尝试在Typescript中执行时出现异步/等待问题,但可以在Javascript中工作
我有一个支持javascript脚本的客户端应用程序。应用程序是用Typescript编写的。 虽然一切似乎都按预期进行,但当用户试图在脚本中使用wait时,我遇到了一个问题 我用纯JS重写了这个场景,并做了一些修改。 在这种环境中,它的工作方式与预期的一样,即:当用户按下按钮时,消息框一个接一个地出现 这是小提琴: 但是,当运行脚本时,应用程序中的Typescript代码会同时弹出所有MessageBox,看起来就像等待被忽略一样 我想不出是怎么回事。 这是精简的TS代码:尝试在Typescript中执行时出现异步/等待问题,但可以在Javascript中工作,javascript,typescript,async-await,Javascript,Typescript,Async Await,我有一个支持javascript脚本的客户端应用程序。应用程序是用Typescript编写的。 虽然一切似乎都按预期进行,但当用户试图在脚本中使用wait时,我遇到了一个问题 我用纯JS重写了这个场景,并做了一些修改。 在这种环境中,它的工作方式与预期的一样,即:当用户按下按钮时,消息框一个接一个地出现 这是小提琴: 但是,当运行脚本时,应用程序中的Typescript代码会同时弹出所有MessageBox,看起来就像等待被忽略一样 我想不出是怎么回事。 这是精简的TS代码: function
function makeScript(owner:string, text: string, argsSig: string) {
let _scriptFunc_: any;
let own = owner;
try {
const promiseCode = `let __res = null;let __rej = null;let __promise = new Promise((resolve, reject) => {__res = resolve;__rej = reject;});try {\n`;
const ending = `;\n;__res();} catch (err) { __rej(err);}; return __promise;`;
const scriptSource = "_scriptFunc_ = async function(" + argsSig + ") {\"use strict\";\n" + promiseCode + text + ending + "\n}";
eval(scriptSource);
}
catch (err) {
console.log(err);
return null;
}
const ret = _scriptFunc_.bind(this);
return ret;
}
async function messagebox(_text: string):Promise<string> {
let resolveFunc:Function = null;
let rejectFunc:Function = null;
let promise = new Promise<string>((resolve,reject) => {
resolveFunc = resolve;
rejectFunc = reject;
});
let win = document.createElement("div");
let $win = $(win);
document.body.appendChild(win);
win.innerHTML = `
<div id="messageboxtext"></div>
<button id="accept" style="width:200px;height:50px;">OK</button>
`;
const acceptButton = $("#accept", $win);
const $text = $("#messageboxtext", $win);
$text.text(_text);
$(acceptButton).click(() => {
resolveFunc("ok");
$win.remove();
});
$win.css({'position':'relative','width':'auto', 'height':'auto', 'background-color':'red'});
return promise
}
class Messagebox {
public static async ShowInput(_text: string): any {
return await messagebox(_text);
}
}
class ScriptBuilder {
public scriptThis:any;
public makeScript(owner:string, text: string, argsSig: string): any {
try {
const scr = makeScript.call(this.scriptThis, owner, text, argsSig);
return async (...args: any[]) => {
try {
let ret = await scr(...args);
return ret;
} catch (err) {
console.log(err);
}
};
} catch (err2) {
console.log(err2);
}
}
}
let scrBuilder = new ScriptBuilder();
scrBuilder.scriptThis = {Message:""};
(<any>window).Messagebox = Messagebox;
let _script = scrBuilder.makeScript("scriptName", `
this.Message += await Messagebox.ShowInput(question + ' 1 ');
console.log(this.Message);
this.Message += await Messagebox.ShowInput(question + ' 2 ');
console.log(this.Message);
this.Message += await Messagebox.ShowInput(question + ' 3 ');
console.log(this.Message);
`, "question");
_script("Please press the button");
编辑:这似乎与我的环境有关,因为它在StackBlitz应用程序中工作:
Edit2:我试图更新注入的承诺代码以使脚本异步,但即使这样做也会做同样的事情(不尊重等待):
两个消息框同时弹出。很抱歉找鬼。错误发生在客户端使用中 客户这样做:
this.something = await Messagebox.Show("...").toString();
它不是等待函数,而是等待同步的toString()。
奇怪的javascript没有抱怨这种语法,我浪费了很多时间去弄清楚,因为我没有用户在脚本中尝试的确切代码。你检查过发出的javascript吗?您是什么版本的JS
--target
-ing?顺便说一句,如果你想分享一个可运行的TS东西,你可能想尝试一下或者类似的东西,而不是JSFiddleTypescript 3.9.7,我会用更多的信息更新这个问题。编译的脚本源代码中的promiseCode
和结束没有任何意义(在文本中打断等待).对你有用吗?如果是这样,那么问题不在于代码,而在于您的环境。理想情况下,您将提供一个其他人可以直接查看以了解问题的解决方案。否则会有很多猜测和看不见的远程调试。@Bergi不,这不会破坏任何东西:我在Stackblitz中添加了一个编辑和一个工作示例。似乎是我的环境造成的。
async ƒ (match, line) {
let p = new Promise((resolve, reject) => {
(async () => {
try {
await Messagebox.ShowInput("...");
await Messagebox.ShowInput("...");
resolve('')
} catch (err) {
reject(err)
}
})()
});
return p;
}
this.something = await Messagebox.Show("...").toString();