尝试在Typescript中执行时出现异步/等待问题,但可以在Javascript中工作

尝试在Typescript中执行时出现异步/等待问题,但可以在Javascript中工作,javascript,typescript,async-await,Javascript,Typescript,Async Await,我有一个支持javascript脚本的客户端应用程序。应用程序是用Typescript编写的。 虽然一切似乎都按预期进行,但当用户试图在脚本中使用wait时,我遇到了一个问题 我用纯JS重写了这个场景,并做了一些修改。 在这种环境中,它的工作方式与预期的一样,即:当用户按下按钮时,消息框一个接一个地出现 这是小提琴: 但是,当运行脚本时,应用程序中的Typescript代码会同时弹出所有MessageBox,看起来就像等待被忽略一样 我想不出是怎么回事。 这是精简的TS代码: function

我有一个支持javascript脚本的客户端应用程序。应用程序是用Typescript编写的。 虽然一切似乎都按预期进行,但当用户试图在脚本中使用wait时,我遇到了一个问题

我用纯JS重写了这个场景,并做了一些修改。 在这种环境中,它的工作方式与预期的一样,即:当用户按下按钮时,消息框一个接一个地出现

这是小提琴:

但是,当运行脚本时,应用程序中的Typescript代码会同时弹出所有MessageBox,看起来就像等待被忽略一样

我想不出是怎么回事。 这是精简的TS代码:

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