我正在尝试实现以下功能:
执行回叫 解决承诺 检查输出 如果不正确再次执行我用计时器“模仿”了这个场景,重新运行了一个脚本,该脚本调用后端数据库获取一些信息:
_runCheckScript: function(bStart, bPreScript){ var oController = this; var scriptTimerdeferred = $.Deferred(); var promise = scriptTimerdeferred.promise(); if(typeof(bStart) === "undefined"){ bStart = true; } if(typeof(bPreScript) === "undefined"){ bPreScript = true; } // if the HANA DB is not stopped or started, i.e. it is still starting up or shutting down // check the status again every x number of seconds as per the function var msTime = 10000; if(!bPreScript){ this._pushTextIntoConsoleModel("output", {"text":"The instance will be 'pinged' every " + msTime/1000 + " seconds for 2 minutes to monitor for status changes. After this, the script will be terminated."}); } if(bPreScript){ var timesRun = 0; var commandTimer = setInterval( function () { timesRun += 1; if(timesRun === 12){ scriptTimerdeferred.reject(); clearInterval(commandTimer); } // send the deferred to the next function so it can be resolved when finished oController._checkScript(scriptTimerdeferred, bStart, bPreScript); }, msTime); } return $.Deferred(function() { var dbcheckDeffered = this; promise.done(function () { dbcheckDeffered.resolve(); console.log('Check finished'); oController._pushTextIntoConsoleModel("output", {"text":"Check finished."}); }); });它调用的脚本有自己的承诺,因为它调用另一个函数:
_checkScript: function(scriptTimerdeferred, bStart, bPreScript){ var oProperties = this.getView().getModel("configModel"); var oParams = oProperties.getProperty("/oConfig/oParams"); var deferred = $.Deferred(); var promise = deferred.promise(); var sCompareStatus1 = "inProg"; var sCompareStatus2 = this._returnHanaCompareStatus(bStart, bPreScript); var sCompareStatus3 = this._returnHanaCompareStatus3(bStart, bPreScript); var params = {//some params}; // Send the command this._sendAWSCommand(params, deferred); // When command is sent promise.done(function (oController) { console.log('back to db check script'); var oCommandOutputModel = oController.getView().getModel("commandOutput"); var sStatus = oCommandOutputModel.Status; // check that it's not in the wrong status for a start/stop // or if it's a pre script check -> pre script checks always resolve first time if(sStatus !== sCompareStatus1 && sStatus !== sCompareStatus2 && sStatus !==sCompareStatus3|| bPreScript){ scriptTimerdeferred.resolve(); } }); },这是有效的,但它的作用是:
设置一个计时器每隔x秒调用第一个脚本(因为数据当前正在改变 - 服务器即将上线) 脚本运行并调用另一个函数从数据库中获取一些数据 当数据调用被解析(完成)时,它返回到checkScript上的'promise.done',并且只有在满足特定条件时才解析定时器承诺 一直以来,初始计时器正在重新发送呼叫,因为最终数据库将联机并且状态将发生变化我想知道是否有更好的方法来执行此操作,因为目前我可能有,例如,3个调用数据库未解决然后所有解决方案同时解决。 我宁愿运行一个命令,等待它解决,检查输出,如果不正确则再次运行命令。
谢谢!
I am trying to achieve the following functionality:
execute call back resolve promise check output if not correct execute againI have 'mimicked' the scenario with a timer, this reruns a script that makes a call to backend database for some information:
_runCheckScript: function(bStart, bPreScript){ var oController = this; var scriptTimerdeferred = $.Deferred(); var promise = scriptTimerdeferred.promise(); if(typeof(bStart) === "undefined"){ bStart = true; } if(typeof(bPreScript) === "undefined"){ bPreScript = true; } // if the HANA DB is not stopped or started, i.e. it is still starting up or shutting down // check the status again every x number of seconds as per the function var msTime = 10000; if(!bPreScript){ this._pushTextIntoConsoleModel("output", {"text":"The instance will be 'pinged' every " + msTime/1000 + " seconds for 2 minutes to monitor for status changes. After this, the script will be terminated."}); } if(bPreScript){ var timesRun = 0; var commandTimer = setInterval( function () { timesRun += 1; if(timesRun === 12){ scriptTimerdeferred.reject(); clearInterval(commandTimer); } // send the deferred to the next function so it can be resolved when finished oController._checkScript(scriptTimerdeferred, bStart, bPreScript); }, msTime); } return $.Deferred(function() { var dbcheckDeffered = this; promise.done(function () { dbcheckDeffered.resolve(); console.log('Check finished'); oController._pushTextIntoConsoleModel("output", {"text":"Check finished."}); }); });The script it calls, has it's own promise as it calls another function:
_checkScript: function(scriptTimerdeferred, bStart, bPreScript){ var oProperties = this.getView().getModel("configModel"); var oParams = oProperties.getProperty("/oConfig/oParams"); var deferred = $.Deferred(); var promise = deferred.promise(); var sCompareStatus1 = "inProg"; var sCompareStatus2 = this._returnHanaCompareStatus(bStart, bPreScript); var sCompareStatus3 = this._returnHanaCompareStatus3(bStart, bPreScript); var params = {//some params}; // Send the command this._sendAWSCommand(params, deferred); // When command is sent promise.done(function (oController) { console.log('back to db check script'); var oCommandOutputModel = oController.getView().getModel("commandOutput"); var sStatus = oCommandOutputModel.Status; // check that it's not in the wrong status for a start/stop // or if it's a pre script check -> pre script checks always resolve first time if(sStatus !== sCompareStatus1 && sStatus !== sCompareStatus2 && sStatus !==sCompareStatus3|| bPreScript){ scriptTimerdeferred.resolve(); } }); },This works, however what it does is:
set a timer to call the first script every x seconds (as the data is currently changing - a server is coming online) the script runs and calls another function to get some data from the DB when the call for data is resolved (complete) it comes back to 'promise.done' on the checkScript and only resolves the timer promise if it meets certain criteria all the while, the initial timer is resending the call as eventually the DB will come online and the status will changeI am wondering if there is a better way to do this as currently I could have, for example, 3 calls to the DB that go unresolved then all resolve at the same time. I would prefer to run a command, wait for it to resolve, check the output, if it is not right then run command again.
Thanks!
最满意答案
我认为您想要做的事情可以通过仔细阅读这些链接中解释的内容来实现:
承诺重试设计模式
在javascript中,一个返回promise并重试内部异步进程最佳实践的函数
看到这个jsfiddle
var max = 5; var p = Promise.reject(); for(var i=0; i<max; i++) { p = p.catch(attempt).then(test); } p = p.then(processResult).catch(errorHandler); function attempt() { var rand = Math.random(); if(rand < 0.8) { throw rand; } else { return rand; } } function test(val) { if(val < 0.9) { throw val; } else { return val; } } function processResult(res) { console.log(res); } function errorHandler(err) { console.error(err); }由于不满足条件,它无限次地重试承诺。 你说的条件是“检查输出”。 如果您的检查失败,请重试承诺。 #小心保持极限情况,承诺浪费记忆。 如果您的api / service / server / callreceiver已关闭,并且您没有设置阈值,则可以创建一个无限的承诺链NO STOP
I think what you want to do can be achieved carefully reading what explained in these links:
Promise Retry Design Patterns
In javascript, a function which returns promise and retries the inner async process best practice
See this jsfiddle
var max = 5; var p = Promise.reject(); for(var i=0; i<max; i++) { p = p.catch(attempt).then(test); } p = p.then(processResult).catch(errorHandler); function attempt() { var rand = Math.random(); if(rand < 0.8) { throw rand; } else { return rand; } } function test(val) { if(val < 0.9) { throw val; } else { return val; } } function processResult(res) { console.log(res); } function errorHandler(err) { console.error(err); }It retries a promise infinite times since the condition is not satisfied. Your condition is the point you said "check the output". If your check fails, retry the promise. # Be careful to hold a limit case, promises waste memory. If your api/service/server/callreceiver is off, and you don't set a threshold, you could create an infinite chain of promises NO STOP
更多推荐
发布评论