2014-10-27 49 views
1

如何在QML中超時XMLHttpRequest?我有以下代碼,但它不會超時。看起來超時功能沒有實現!?有沒有其他的方法來實現超時?在QML中超時XMLHttpRequest

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)); 

編輯: 的代碼是不是在QML,但在一個js文件。它不會進入qml文件,因爲它是模型的一部分(MVC)。

回答

3

看起來QMLXMLHttpRequest不支持timeout函數。 這是功能/特性支持的子集的列表:

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

但是你可以使用QMLTimer項目爲這個目的,例如:

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(); 
      } 
     } 
    } 
} 
+0

是啊,我知道定時器。問題是,代碼在模型中,這是一個JavaScript文件。 – Michael 2014-10-28 19:41:31

+0

關於你的代碼:不應該計時器調用'req.abort()'? – Michael 2014-10-28 19:43:11

+0

好吧,如果我們不能使用'XMLHttpRequest.timeout()'並且我們不能使用'setTimeout()',我們仍然可以在'JS'中創建'Timer'並使用它。我已經更新了我的答案,請檢查它。我還在代碼中使用了req.abort()。 – folibis 2014-10-28 23:26:00

1

全局的setTimeout()setInterval()用於對瀏覽器中的功能進行建模的實用程序。

它可以用來間接超時一個XMLHttpRequest。或者在應用程序的其他地方謹慎使用。

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

主要QML片段

用下面的代碼,任何孩子能夠訪問app.util.timer命名空間下的方法(或util.timer命名空間,如果JS代碼被加載到主代碼隱藏文件中)。

import "CodeBehind.js" as CodeBehind 

id: appWindow 

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

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

代碼隱藏JS代碼片段

var util = util || {}; 

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

實用JS文件

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; 
};