JavaScript - 时间问题 - 如何等待请求

时间:2017-09-01 10:23:32

标签: javascript jquery

我有一张需要根据AJAX调用结果显示的图像。我没有加载jQuery和其他类似于Foundation的库,它负责根据设备加载负责任的图像。

AJAX呼叫的响应时间范围为800-1000毫秒。如果响应时间超过1000毫秒,我会显示默认图像。此外,我应该在加载时将AJAX请求作为第一个请求发送,因此它会立即设置为标头的第一个子节点。 JSFiddle for Timing issue

<html><head><script>set Timeout of 1000 ms .....xhr.send();</script>
<body>
  <div id="id_in_response" style="display:none"><img src="xyz"></div>
  <div id="default_on_timeout" style="display:none"><img src="xyz"></div>
....Loads of Elements.....
<footer>
  <script src="jquery.js"></script>
  <script src="foundation.js"></script>
  <script src="custom.js"></script>
</body>

自定义js的说明: 自定义js将执行Foundation库js以加载响应式图像。

问题是XHR应该如何与custom.js函数通信,要么必须处理TIMEOUT OR Response。我不能使用jQuery Promise,因为jQuery将在下载HTML后加载。我还不能使用Native Promises。 可能是在XHR响应进入时,但custom.js仍然没有加载或被解析。我也不能假设共振时间总是在800-1000毫秒的范围内。它甚至可以降至300毫秒或更短。

Custome JS代码:

$(document).foundation({interchange : named_queries {....}}); 

 // This will parse all the image tags , Run media Query and attach an 
 appropriate source to the image

最终解决方案:enter link description here

2 个答案:

答案 0 :(得分:1)

穷人“未来”代码

var specialRequest = (function() {
    var cb;
    var cberr;
    var xhr = new XMLHttpRequest();
    var doCallback = function(err) {
        if (cb === undefined) {
            cb = true;
            cberr = err;
        } else if (typeof cb === 'function') {
            cb(err, xhr);
        }
    };
    var timeout = setTimeout(function() {
        xhr.abort(); //??
        doCallback('timeout');
    }, 1000);
    xhr.open('GET', 'whatever/your/url/is');
    xhr.onload = function() {
        doCallback(null);
    }
    xhr.onerror = function() {
        doCallback('error');
    }
    xhr.onloadend = function() {
        // if the XHR finishes before the setTimeout, cancel it
        clearTimeout(timeout);
    }
    xhr.send();

    return function(callback) {
        if (cb === undefined) {
            cb = callback;
        } else if (cberr !== null) {
            callback(cberr, xhr);
        }
    }
})();

然后,在custom.js

specialRequest(function(error, xhr) {
    if (error) {
        // handle error
    } else {
        // handle success
    }
});

将此与Promise代码进行比较

var myPromise = new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    var timeout = setTimeout(function() {
        reject(new Error('timeout'));
    }, 1000);
    xhr.open('GET', 'whatever/your/url/is');
    xhr.onload = function() {
        resolve(xhr);
    }
    xhr.onerror = function() {
        reject(new Error('error'));
    }
    xhr.send();
});

//在custom.js

myPromise.then(function(xhr) {
    // handle success
}).catch(function(reason) {
    // handle failure
});

答案 1 :(得分:0)

  

我应该使用setInterval - 不会阻止页面吗?

不,它不会;但是你使用setTimeout而不是setInterval来建立你的1000ms超时。例如,粗略

var timer = setTimeout(function() {
    // Use default image instead
}, 1000);
var xhr = new XMLHttpRequest(/*...*/);
xhr.send(/*...*/);
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
        if (/*...you haven't already used the default image...*/) {
            clearTimeout(timer);
            // Use the appropriate image...
        }
    }
};

请注意,上述内容并不会阻止页面的显示,我强烈建议这样做。只需在知道要填写的图像时填写图像(如上所述)。