JavaScript 回调被保存在内存中并用新的回调执行

JavaScript Callback being kept in memory and excuted with new callback

我正在使用 ajax 进行 CMS 类型的项目。我的问题出现在 notify.js javascript 库 https://notifyjs.com/.

通过我的本地副本,我意识到我可以创建设计精美的确认按钮,而无需使用 Javascript 内置的 alert()confirm() 方法,并使其看起来像这样:

看到源码没有提供显式添加库外回调的方法,我按照自己的意愿修改了它,其中"callback"参数是我的自定义参数

I.E.

    //confirmation notification
    Notification.prototype.confirm = function (style, position, title, text, callback) {
        var icon = "fa fa-adjust";
        if (style == "error") {
            icon = "fa fa-exclamation";
        } else if (style == "warning") {
            icon = "fa fa-warning";
        } else if (style == "success") {
            icon = "fa fa-check";
        } else if (style == "info") {
            icon = "fa fa-question";
        } else {
            icon = "fa fa-adjust";
        }
        $.notify({
            title: title,
            text : text + '<div class="clearfix"></div><br><a id="yesConfirmBtn" class="btn btn-sm btn-default yes">Yes</a><a id="noConfirmBtn"  class="btn btn-sm btn-danger no">No</a>',
            image: "<i class='" + icon + "'></i>"
        }, {
            style         : 'metro',
            className     : style,
            globalPosition: position,
            showAnimation : "show",
            showDuration  : 0,
            hideDuration  : 0,
            autoHide      : false,
            clickToHide   : false
        });
        //listen for click events from this style
        $(document).on('click', '.notifyjs-metro-base .no', function () {
            // turn off event listener on yes click
            $(document).off("click", '.notifyjs-metro-base .yes');

            //programmatically trigger propogating hide event
            $(this).trigger('notify-hide');
        });
        var yesClick = function () {
            //callback when user clicks
            callback();
            // callback is assigned empty closure  because on
            // the next confirm request this callback and
            // the new one will be called
            callback = function(){

            };

            //hide notification
            $(this).trigger('notify-hide');

        };
        $(document).on('click', '.notifyjs-metro-base .yes', yesClick);
    }

在点击侦听器中,我的问题出现在 yesClick 侦听器中,主要是因为它继续一个接一个地添加回调,因此每次创建并触发回调时,都会触发旧回调,然后触发其余回调,直到最新回调

为了绕过这个问题,我将回调指向一个空的匿名函数,所以当执行旧函数时它不会做任何事情,但这种方式仍然不能解决我的问题,因为回调仍然存在内存。

传入的回调执行Ajax删除数据库中一行的请求。

这就是回调的样子

var self = this;
// triggers notify.js confirmDelete() method passing in the 
// body, title, and callback
this.notif.confirmDelete("Are you sure?", "Delete this Item?", function () {
    // creates a notification to show user their 
    // transaction is being processed
    self.notif.info("Deleting");
    // callback for if the ajax request was successful
    var successCB = function (text) {
        if (text.indexOf("true") !== -1) {
            self.notif.success("Item has been deleted", "Successfully Deleted");
            var form  = new Validate(),
                table = new Table();
            form.resetForm();
            table.removeRow(data.id);
        } else {
            self.notif.error("Could not be deleted...");
        }
      // callback if ajax request failed
    }, failCB     = function () {
        // this key word refer's to a method called 
        //Success which is the same as  successCB as they
        //are placed in the same object literal
        this.Success("false");
    };
    self.ajaxRequest(successCB, failCB, data);
});

self.ajaxRequest 看起来像这样(这是我制作的自定义 ajax 库,如果它看起来很奇怪)

 var self          = this;
var dataToProcess = data || {};
// basic set up for ajax request
Ajaxify({
    host        : self.hostName + "Backend/manage/" + self.processFile,
    data        : [dataToProcess],
    responseType: "text",
    method      : "POST",
    execute     : true,// executes request right away
    Success     : successCallback,
    Failure     : failureCallback
});

我做错了什么?

我该如何解决这个问题?

是什么原因造成的?

(注意:如果需要任何进一步的信息,请告诉我)

您需要使用 off 删除点击事件,因为您要使用 on

添加全局点击
   function noClick() {
        //programmatically trigger propogating hide event
        $(this).trigger('notify-hide');
        removeEvents();
   }
   function removeEvents() {
       $(document).off('click', '.notifyjs-metro-base .no', noClick);
       $(document).off('click', '.notifyjs-metro-base .yes', yesClick);
   }
   $(document).on('click', '.notifyjs-metro-base .no', no);
   function yesClick () {
        //callback when user clicks
        callback();

        //hide notification
        $(this).trigger('notify-hide');
        removeEvents();
    };
    $(document).on('click', '.notifyjs-metro-base .yes', yesClick);