延期承诺 - 如果回调不符合标准,则重新发送相同的请求

时间:2017-05-09 21:07:57

标签: javascript jquery timer promise deferred

我正在尝试实现以下功能:

  • 执行回叫
  • 解除承诺
  • 检查输出
  • 如果不正确再次执行

我已经模仿了'带有计时器的场景,重新运行一个脚本,该脚本调用后端数据库以获取一些信息:

 _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秒调用第一个脚本(因为数据当前正在更改 - 服务器即将上线)
  • 脚本运行并调用另一个函数从DB获取一些数据
  • 当数据呼叫被解决(完成)时,它会回到' promise.done'在checkScript上,如果符合某些条件,则只解析计时器承诺
  • ,初始计时器重新发送呼叫,因为最终数据库将联机并且状态将更改

我想知道是否有更好的方法来执行此操作,因为目前我可能有,例如,3个调用数据库未解决然后全部同时解析。我宁愿运行一个命令,等待它解决,检查输出,如果不对,那么再次运行命令。

谢谢!

1 个答案:

答案 0 :(得分:1)

我认为您想要做的事情可以通过仔细阅读这些链接中解释的内容来实现:

Promise Retry Design Patterns

In javascript, a function which returns promise and retries the inner async process best practice

See this jsfiddle

import Foundation
import UIKit
import GoogleMaps

class MapViewController: UIViewController {

    struct Place {
        let id: Int
        let name: String
        let lat: CLLocationDegrees
        let lng: CLLocationDegrees
        let icon: String
    }

    @IBOutlet weak var mapView: GMSMapView!
    var markerDict: [Int: GMSMarker] = [:]

    var zoom: Float = 15

    override func viewDidLoad() {
        super.viewDidLoad()

        let camera = GMSCameraPosition.camera(withLatitude: 34.1381168, longitude: -118.3555723, zoom: zoom)
        self.mapView.camera = camera

        do {
            if let styleURL = Bundle.main.url(forResource: "style", withExtension: "json") {
                mapView.mapStyle = try GMSMapStyle(contentsOfFileURL: styleURL)
            } else {
                NSLog("Unable to find style.json")
            }
        } catch {
            NSLog("One or more of the map styles failed to load. \(error)")
        }

        let places = [
            Place(id: 0, name: "MrMins", lat: 34.1331168, lng: -118.3550723, icon: "i01"),
        ]

        for place in places {
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude: place.lat, longitude: place.lng)
            marker.title = place.name
            marker.snippet = "Custom snipet message \(place.name)"
            marker.appearAnimation = kGMSMarkerAnimationPop
            //marker.icon = self.imageWithImage(image: UIImage(named: place.icon)!, scaledToSize: CGSize(width: 35.0, height: 35.0))
            marker.map = self.mapView

            markerDict[place.id] = marker
        }

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



    @IBAction func btnZoomIn(_ sender: Any) {
        zoom = zoom + 1
        self.mapView.animate(toZoom: zoom)
    }

    @IBAction func btnZoomOut(_ sender: Any) {
        zoom = zoom - 1
        self.mapView.animate(toZoom: zoom)
    }


}

由于不满足条件,它无限次重试承诺。你说的条件是“检查输出”。如果您的检查失败,请重试承诺。 #小心保持极限情况,承诺浪费记忆。如果您的api / service / server / callreceiver已关闭,并且您没有设置阈值,则可以创建一个无限的承诺链NO STOP