使用异步功能时如何防止关闭引导箱?

How to prevent closing bootbox while using async function?

我想要得到的是,如果用户遇到任何验证错误,那么引导框将显示“这是必需的”.到现在为止,我已经实现了这一点。但主要问题是 - 如果用户单击 “是” 按钮,它会关闭引导框的 window。 我得到这个是因为我必须在 bootbox 中使用 g async callback 。因此,即使在返回 false 之后,bootbox 也会关闭。但我希望用户显示该框,直到他们按下 取消 按钮。如果他们点击 Yes,那么它应该显示验证,并打开该框。这是我的代码:

bootbox.confirm({
    message: 'Test',
    buttons: {
        confirm: {
            label: 'Yes',
            className: 'btn-primary'
        },
        cancel: {
            label: 'No',
            className: 'btn-danger'
        }
    },
    callback: async function (result) {
        var isValid = $('#form').valid();
        if (result && !isValid) {
            return false; //it's not working. It's closing the bootbox
        }
        if (result && isValid) {
            /* for this await function I had to use async callback,
               without this bootbox is opend
            */
            var data = await self.createData();
            $.ajax({
                type: "POST",
                success: function (result) {

                },
            }).then(function () {
            });
        }
    }
});

我该如何解决?

在我看来,bootbox.confirm()async 回调没有任何形式的支持,就像您尝试使用的那样。当你的回调 returns 将在你点击第一个 await 时关闭引导框,除非你明确地 return false,但是 async 回调函数始终 return 是一个未明确 false 的承诺。你不能改变它。

你可以做的是让你的回调成为一个常规回调函数,而不是 async 如果验证失败可以 return false 然后创建一个嵌入式 async 函数您可以在第一个回调中使用 await 调用的位置,如下所示。请注意,bootbox 将在您的异步代码完成之前关闭,因此如果 bootbox 代码中有任何错误,您将需要以新的方式来呈现这些错误,也许是建立一个新的 bootbox。这是在仍然使用 await.

的同时执行此代码的一种方法
bootbox.confirm({
    message: 'Test',
    buttons: {
        confirm: {
            label: 'Yes',
            className: 'btn-primary'
        },
        cancel: {
            label: 'No',
            className: 'btn-danger'
        }
    },
    callback: function (result) {
        var isValid = $('#form').valid();
        if (result) {
            if (!isValid) {
                // keep prompt open until user presses Cancel
                return false;
            }

            async function run() {
                const data = await self.createData();
                const result = await $.ajax({ ... });
                // do something with result
            }
            // now call async function here (dialog will close)
            run().catch(err => {
                // do something with an error here
                console.log(err);
            });
        }
        return true;
    }
});

或者,您可以避免使用 await,而只使用 .then().catch(),这样就不需要额外的函数层了:

bootbox.confirm({
    message: 'Test',
    buttons: {
        confirm: {
            label: 'Yes',
            className: 'btn-primary'
        },
        cancel: {
            label: 'No',
            className: 'btn-danger'
        }
    },
    callback: function (result) {
        var isValid = $('#form').valid();
        if (result) {
            if (!isValid) {
                // keep prompt open until user presses Cancel
                return false;
            }

            self.createData().then(data => {
                return $.ajax({ ... }).then(result => {
                    // do something with result
                });
            }).catch(err => {
                // do something with error here
                console.log(err);
            });
        }
        return true;
    }
});