等待异步函数在Typescript中返回一个值。

时间:2017-10-26 19:49:58

标签: angular typescript asynchronous promise wait

我有一个函数(Function1),它调用另一个返回字符串的函数(Function2)。

我希望Function1调用Function2,但等待并获取Function2的返回值。你是怎么做的?这是我的代码(不能按预期工作):

这是我的Function1:

async Function1() {
    const message = await this.dialogButtonPress();
    alert(message);
}

这是我的功能2:

async dialogButtonPress() : Promise<string> {
    const doneButtonPromise = new Promise((resolve) => {
        const doneButton = document.getElementById("done-button");
        const resolver = () => {
            resolve();
            doneButton.removeEventListener("click", resolver);
        }
        doneButton.addEventListener("click", resolver);
    });

    const cancelButtonPromise = new Promise((resolve) => {
        const cancelButton = document.getElementById("cancel-button");
        const resolver = () => {
            resolve();
            cancelButton.removeEventListener("click", resolver);
        }
        cancelButton.addEventListener("click", resolver);
    })

    doneButtonPromise.then(() => {
        console.log("DONE BUTTON PRESSED!");
        return "Confirm";

    });

    cancelButtonPromise.then(() => {
        console.log("CANCEL BUTTON PRESSED!");
        return "Cancel";
    });      
}

2 个答案:

答案 0 :(得分:3)

如果您使用Promise.race作为other answer建议,那么您将无法清除按下的按钮的事件处理程序。您只清理 按下的按钮的处理程序。如果是我,我只是组合事件处理程序,以确保在按下任何按钮时清除所有内容:

async dialogButtonPress(): Promise<string> {
    return new Promise<string>((resolve) => {
        const doneButton = document.getElementById("done-button")!;
        const cancelButton = document.getElementById("cancel-button")!;
        const resolver = (ev: Event) => {
            doneButton.removeEventListener("click", resolver);
            cancelButton.removeEventListener("click", resolver);
            // This is where we determine which button was clicked.
            resolve(ev.target === doneButton ? "Confirm" : "Cancel");
        }
        doneButton.addEventListener("click", resolver);
        cancelButton.addEventListener("click", resolver);
    });
}

它可以扩展到任意数量的按钮:

async dialogButtonPress(): Promise<string> {
    return new Promise<string>((resolve) => {
        // You just need to expand this map in order to support additional buttons.
        const idToResponse: Record<string, string> = {
            "done-button": "Confirm",
            "cancel-button": "Cancel",
        };
        const buttons = Object.keys(idToResponse).map((id) => document.getElementById(id)!);
        const resolver = (ev: MouseEvent) => {
            for (const button of buttons) {
                button.removeEventListener("click", resolver);                    
            }
            // We index into idToResponse to convert the button's id to a specific response.
            resolve(idToResponse[(ev.target as Element).id]);
        }

        for (const button of buttons) {
            button.addEventListener("click", resolver);
        }
    });
}

答案 1 :(得分:2)

更改

doneButtonPromise.then(() => {
    console.log("DONE BUTTON PRESSED!");
    return "Confirm";

});

cancelButtonPromise.then(() => {
    console.log("CANCEL BUTTON PRESSED!");
    return "Cancel";
});

return Promise.race([
    doneButtonPromise.then(() => {
        console.log("DONE BUTTON PRESSED!");
        return "Confirm";
    }),
    cancelButtonPromise.then(() => {
        console.log("CANCEL BUTTON PRESSED!");
        return "Cancel";
    })
]);