Javascript 承诺+;jqueryajax链使内存增长。我用对了吗?

Javascript 承诺+;jqueryajax链使内存增长。我用对了吗?,javascript,jquery,ajax,memory-leaks,promise,Javascript,Jquery,Ajax,Memory Leaks,Promise,我有一个JS,它必须定期执行远程操作,然后对其做出反应。流程是: - Start the operation in main script -> `setInterval` calling a function every 5 seconds -> This function waits for a `Promise` that internally... -> ... calls `$.ajax`, validate the response,

我有一个JS,它必须定期执行远程操作,然后对其做出反应。流程是:

- Start the operation in main script
  -> `setInterval` calling a function every 5 seconds
     -> This function waits for a `Promise` that internally...
        -> ... calls `$.ajax`, validate the response, then resolve or reject.
我看到我的应用程序内存在增长,这个操作链可能是原因。我使用承诺的方式正确吗

主要的切入点很简单:

StateWatcher.startWatchSystem();
然后,所涉及的模块:

var StateWatcher = {

    // is called by the main app to start the backround check every 5 sec
    // the actual function that performs the update is "doSystemStateUpdate"
    startWatchSystem: function() {    
        this.doSystemStateUpdate();
        this.systemWatchTimeout = setInterval(() => {
            this.doSystemStateUpdate();
        }, 5000)
    },

    <...>

    // this is "doSystemStateUpdate": the remote call is performed by another module "RemoteQuery.getSystemState()".
    // that last function returns a Promise (see below), so I can check the result with "then" and "catch"
    doSystemStateUpdate: function() {
        RemoteQuery.getSystemState()
        .then((data) => {
            // ok, got the new State
            this.currentSystemState = data.Message;
            // ... inform other modules etc etc...
        })
        .catch((error) => {
            Logger.write("error", "doSystemStateUpdate:");
            Logger.write("error", error);
        });
    }
}
var StateWatcher={
//由主应用程序调用,每5秒启动一次回溯检查
//执行更新的实际函数是“doSystemStateUpdate”
startWatchSystem:函数(){
this.doSystemStateUpdate();
this.systemWatchTimeout=setInterval(()=>{
this.doSystemStateUpdate();
}, 5000)
},
//这是“doSystemStateUpdate”:远程调用由另一个模块“RemoteQuery.getSystemState()”执行。
//最后一个函数返回一个承诺(见下文),因此我可以用“then”和“catch”检查结果
doSystemStateUpdate:函数(){
RemoteQuery.getSystemState()
。然后((数据)=>{
//好的,有了新的状态
this.currentSystemState=data.Message;
//…通知其他模块等。。。
})
.catch((错误)=>{
write(“错误”,“doSystemStateUpdate:”);
Logger.write(“错误”,error);
});
}
}
以下是“RemoteQuery”模块:

var-RemoteQuery={
连接错误:错误,
//getSystemState在内部调用jQueryAjax,但随后将其封装在一个承诺中
//当Ajax完成时,在实际解决承诺之前,它必须使用函数“validateResponse”对Ajax结果进行快速检查
getSystemState:函数(){
返回新承诺((解决、拒绝)=>{
$.ajax({
数据类型:“json”,
网址:,
方法:“获取”,
cache:false,
成功:函数(数据){RemoteQuery.validateResponse(true,resolve,data)},
错误:函数(xhr,opts,error){RemoteQuery.validateResponse(false,reject,xhr)}
});
})
}
//这是最后一步:如果ajax操作不正常,此函数将设置一个“报警”标志。
//最后,它调用函数来解析承诺
validateResponse:函数(确定,然后是args){
if(this.connectionError==false&&ok==false){
this.connectionError=true;
//做其他事情(记录等)
}
else if(this.connectionError==true&&ok==true){
this.connectionError=false;
//做其他事情(记录等)
}
然后(args);//现在根据在ajax->success或ajax->error之后调用它的方式来解析或拒绝
},
}

因此,即使前一个请求尚未完成,您也希望每5秒请求一次吗?另外,ajax文档声明,
.then()
promise是
成功回调选项的另一种构造
,因此我想这是您的代码“遵循两个方向”的地方,而不是在done()/then()或success()中执行所有操作看不到任何可能导致内存泄漏的内容,但您可以通过编写
返回$.ajax(…)。然后(…).catch(…)
并放弃
新承诺()
包装来简化。此模式还允许您将
validateResponse()
代码滚动到
getSystemState()
中,并允许
validateResponse()
响应作为单独的函数消失。这是一个更好的解决方案,尽管我怀疑它能修复内存泄漏。@Roamer-1888我知道我可以用then/catch(但为什么不能用done/fail?)替换jQuery的错误/成功。。。无论如何,我不确定为什么这将允许我删除
validateResponse()
。如何在
getSystemState()
中滚动它?它也被其他函数使用,所以我没有信心复制/粘贴它的主体。。。你能提供一个代码示例吗?如果在别处调用了
validateResponse()
,请忽略我的建议。您仍然应该使用
.then()
&
.catch()
。在jQueryV3+中,它们具有所谓的“过滤能力”,成功:/error:`and.done()
&
.fail()`not。使用
.then()
.catch()
时,抛出错误的返回值将沿着承诺链传播。
var RemoteQuery = {

    connectionError: false,

    // the getSystemState internally calls jQuery AJAX but then enclose it in a Promise
    // When Ajax finishes, before actually resolve the promise it must do a quick check on the Ajax result, using function "validateResponse"
    getSystemState: function () { 
        return new Promise((resolve, reject) => {
            $.ajax({
                dataType: "json",
                url: <.... http...>,
                method: "GET",
                cache: false,
                success: function(data) { RemoteQuery.validateResponse(true, resolve, data) },
                error: function(xhr, opts, error) { RemoteQuery.validateResponse(false, reject, xhr) }
            });
        })
    }

    <...>

    // this is the last step: this function sets an "alarm" flag if the ajax operation was not ok.
    // at the end, it calls the function to resolve the promise
    validateResponse: function(ok, then, args) {
        if (this.connectionError == false && ok == false) {
            this.connectionError = true;
            // do other stuff (logging,...)
        }
        else if (this.connectionError == true && ok == true) {
            this.connectionError = false;
            // do other stuff (logging,...)
        }

        then(args); // now resolve or reject based on how it has been called after ajax->success or ajax->error
    },
}