Timeout XMLHttpRequest in QML

99封情书 提交于 2019-12-11 02:07:39

问题


How do I time out a XMLHttpRequest in QML? I have the following code, but it won't time out. It seems the timeout functionality is not implemented!? Is there any other way to achieve timeouts?

var http = new XMLHttpRequest();
http.open("POST", "http://localhost/test.xml", true);
http.setRequestHeader('Content-type', 'application/json; charset=utf-8')

http.timeout = 4000;
http.ontimeout = function () {
    console.log("timed out")
}

http.onreadystatechange = function() {
    if (http.readyState === XMLHttpRequest.DONE) {
        // Do something
    }
}

http.send(JSON.stringify(data));

Edit: The code is not in a qml, but in a js file. And it won't go into a qml file as it is part of the model (MVC).


回答1:


It looks that QML XMLHttpRequest does not support timeout function. This is a list of supported subset of functions/properties:

http://qt-project.org/doc/qt-5/qtqml-javascript-qmlglobalobject.html#xmlhttprequest

But you can use QML Timer item for this purposes, for example:

import QtQuick 2.3

Item {
    id: root
    width: 600
    height: 400

    Text {
        anchors.fill: parent
        id: response
        text: "Click me"
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
        MouseArea {
            anchors.fill: parent
            onClicked: {
                response.text = "Loading...";

                var req = new XMLHttpRequest();

                var timer = Qt.createQmlObject("import QtQuick 2.3; Timer {interval: 4000; repeat: false; running: true;}",root,"MyTimer");
                timer.triggered.connect(function(){
                    req.abort();
                    response.text = "timed out";
                });


                req.open("GET","http://google.com--",true); // correct me
                req.onreadystatechange = function() {

                    if (req.readyState === XMLHttpRequest.DONE && req.status == 200) {
                        response.text = req.getAllResponseHeaders();
                        timer.running = false;
                    }
                }

                req.send();
            }
        }
    }
}



回答2:


A global setTimeout() and setInterval() utility that models the functionality found in browsers.

It can be used to indirectly timeout an XMLHttpRequest. Or used sparingly elsewhere within the application.

timeoutId = util.timer.setTimeout(function() {}, 4500);
util.timer.clearInterval(timeoutId);

Main QML Snippet

With the following code, any child is able to access the methods under the app.util.timer namespace (or util.timer namespace if JS code is loaded in the main codebehind file).

import "CodeBehind.js" as CodeBehind

id: appWindow

QtObject {
     id: app
     property var util: CodeBehind.util
}

Component.onCompleted: {
    CodeBehind.util.timer.init(appWindow);
}

CodeBehind JS Snippet

var util = util || {};

Qt.include("qrc:/Util/Timer.js");

Utility JS File

var util = util || {};

/**
    Mimics the window.setTimeout() and window.setInterval() functionality
    found in browsers.

    @namespace timer
    @memberof util
*/
util.timer = new function() {
    var _timer;
    var _timerList = [];
    var _currentTime = 0;

    var _api = {};
    var _private = {};
    var _enums = {};



    /*************** Private ENUMS ***************/
    _enums.type = {
        timeout: 0,
        interval: 1
    };



    /*************** Public API Methods ***************/
    /**
        Mimics the window.setTimeout() functionality found in browsers.

        @param {function} callback
        @param {int} interval Milliseconds

        @public
        @memberof util.timer
    */
    _api.setTimeout = function(callback, interval) {
        var timer, id;
        id = parseInt(Math.random() * Date.now());
        timer = new Timer(id, callback, interval, _enums.type.timeout);
        _timerList.push({ id: id, timer: timer });
        return id;
    };


    /**
        Mimics the window.setInterval() functionality found in browsers.

        @param {function} callback
        @param {int} interval Milliseconds

        @public
        @memberof util.timer
    */
    _api.setInterval = function(callback, interval) {
        var timer, id;
        id = parseInt(Math.random() * Date.now());
        timer = new Timer(id, callback, interval, _enums.type.interval);
        _timerList.push({ id: id, timer: timer });
        return id;
    };


    /**
        Clears an interval or timout by the interval id that is returned
        when setTimeout() or setInterval() is called.

        @param {int} intervalId

        @public
        @memberof util.timer
    */
    _api.clearInterval = function(intervalId) {
        var idx, len, idxOfTimer;

        if (_timerList) {
            // Find the index of the timer
            len = _timerList.length;
            for (idx = 0; idx < len; idx++) {
                if (_timerList[idx].id === intervalId) {
                    idxOfTimer = idx;
                    break;
                }
            }

            // Remove the timer from the array
            _timerList.splice(idxOfTimer, 1);
        }

        // If: There are no more timers in the timer list
        // Then: Stop the QML timer element
        if (!_timerList || _timerList.length === 0) {
            _private.stop();
        }
    };



    /*************** Private Helper Methods ***************/
    _private.start = function() {
        _timer.start();
    };

    _private.stop = function() {
        _timer.stop();
        _currentTime = 0;
    };

    _private.runInterval = function() {
        var idx, len, tempList;

        // Increment the current timer
        _currentTime++;

        if (_timerList) {
            // Create a temp list of timers
            tempList = [];
            len = _timerList.length;
            for (idx = 0; idx < len; idx++) {
                tempList.push(_timerList[idx].timer);
            }

            // Trigger each method
            len = tempList.length;
            for (idx = 0; idx < len; idx++) {
                tempList[idx].trigger();
            }
        }
    };



    /*************** Objects ***************/
    /**
        A timer object contains a trigger to check and see if it needs
        to run the callback.

        @param {int} id
        @param {function} callback
        @param {int} interval Milliseconds
        @param {enum} type type.interval | type.timeout

        @public
        @memberof util.timer
    */
    var Timer = function(id, callback, interval, type) {
        var _obj = {};

        _obj.api = {};
        _obj.hasRun = false;
        _obj.endTime = _currentTime + interval;

        _obj.api.trigger = function() {
            if (_currentTime >= _obj.endTime && !_api.hasRun) {
                _obj.hasRun = true;
                callback();

                if (type === _enums.type.interval) {
                    _obj.endTime += interval;
                    _api.hasRun = false;
                }
                else {
                    _api.clearInterval(id);
                }
            }
        };

        _private.start();

        return _obj.api;
    };


    /*************** Initialize ***************/
    _api.init = function(appWindow) {
        _timer = Qt.createQmlObject("import QtQuick 2.3; Timer { interval: 1; repeat: true; running: false;}", appWindow, "timer");
        _timer.triggered.connect(_private.runInterval);
    };


    return _api;
};


来源:https://stackoverflow.com/questions/26598404/timeout-xmlhttprequest-in-qml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!