2015-09-01 77 views
6

我每秒都会向服务器发送一个XMLHttpRequest,服务器会以新消息响应。要每秒调用XMLHttpRequest,我使用SharedWorker内部的setInterval()函数。setInterval()是一个异步函数吗?

但是,由于我每秒都在提出请求,所以我想知道setInterval()是否是异步的?

例如,如果一个XMLHttpRequest请求了3秒完成“由于延迟”,我将有3个请求在同一时间去或将setInterval()等待,直到它等待1秒发送另一个前的第一个请求完成请求?

这里是我的代码

function checkQueue(url) 
{ 
    var xhr = new XMLHttpRequest(); 
    xhr.addEventListener("load", reqListener); 
    xhr.open('GET', url, true); 
    xhr.send(); 
} 


function reqListener() 
{ 
    var queue = JSON.parse(this.responseText); 
    notifyAllPorts(queue); 
    console.log(this.responseText); 
} 


setInterval(
    function() { 
     checkQueue('/add-ons/icws/push.php') 
    } 
, 1000); 
+0

它是异步的,但你不会有3个请求在同一时间进行,因为函数间隔为1秒。无论如何,提供的函数都会每秒执行一次。 – MinusFour

+0

@MinusFour然后我会至少有两个同时进行。如果服务器需要10秒钟响应,则请求将继续。我怎样才能防止这种情况发生? –

+1

你可以用承诺来做到这一点,如果问题是如何间隔承诺,我可以提供一个答案。 – MinusFour

回答

1

正如指出,它不会等到请求完成。下面是间隔一个承诺道:

function checkQueue(url, cb) { 
    var xhr = new XMLHttpRequest(); 
    xhr.addEventListener("loadend", cb); 
     xhr.addEventListener("load", reqListener); 
    xhr.open('GET', url, true); 
    xhr.send(); 
} 

function reqListener() 
{ 
    var queue = JSON.parse(this.responseText); 
    notifyAllPorts(queue); 
    console.log(this.responseText); 
} 

var promise = Promise.resolve(true); 

setInterval(function() { 
    promise = promise.then(function() { 
     return new Promise(function (resolve) { 
      checkQueue(yourUrlHere, resolve); 
     }); 
    }); 
}, 1000); 

它会不断增加的要求做的每一秒,但是,如果它超过1秒就会耽误自己。

+0

以确保我在这里关注你。因此,如果请求需要10秒钟,它是否会创建一个包含请求的队列,并且一旦完成,它会开始运行队列中的请求,直到它出现咳嗽为止? –

+0

如果请求需要10秒钟,这将排队等待8-9个请求完成,但只会在最后一次完成后继续开始。换句话说,在一个小时内,它将排队3600个申请。如果请愿全部持续1秒,那么所有3600份申请将完成。如果申请时间超过1秒,则会延迟下一次申请,直到完成,导致申请不到3600份。 – MinusFour

+0

由于我正在尝试一个问题,此代码每秒生成一个新的TCP连接,因此我稍微调整了一下代码。它不重用一个开放的TCP连接。请看看我发布的另一个问题http://stackoverflow.com/questions/32505128/how-to-make-xmlhttprequest-reuse-a-tcp-connection谢谢你的帮助:) –

1

setInterval只需排队一次代码当前调用堆栈执行完毕运行。这对于某些事情可能有用。

所以是的,它是异步的,因为它打破了同步流程,但它并不会在单独的线程上同时执行。如果你的目标是后台处理,看看webworkers。

所以不管多的时间服务器如何采取它会要求每一秒,按您的代码设置为1000

+0

这是否意味着'setTimeout'将在函数完成后1秒执行一个函数,而不管函数的结果如何,都会执行'setInterval'? –

2

是的,你会碰到麻烦。无论您的请求状态如何,setInterval都会像发条一样脱落。

你最好关闭在每个请求完成开始使用setTimeout一重击定时器......这样:

function checkQueue(url) 
{ 
    var xhr = new XMLHttpRequest(); 
    xhr.addEventListener("load", reqListener); 
    xhr.open('GET', url, true); 
    xhr.send(); 
} 


function reqListener() 
{ 
    var queue = JSON.parse(this.responseText); 
    notifyAllPorts(queue); 
    console.log(this.responseText); 
    setTimeout(
     function() { 
      checkQueue('/add-ons/icws/push.php') 
     }, 1000); 
} 


checkQueue('/add-ons/icws/push.php') 
+0

谢谢你的回答。那么,你会准确地编码吗?它如何保证一个请求只能从一个请求开始完成? –

+0

...因为一旦我们确信先前的请求已完成(即在XMLHttpRequest的'load'事件之后...您的回调被调用,因此请求已完成),我们就只启动一次性计时器。这意味着一旦前一个请求**完成**,我们就等待一秒再重新启动。到底是你想要的,不是? – spender

+0

我明白了。所以这段代码将确保没有请求是触发器,除非现有的请求完成。如果服务器和工作人员之间的连接断开,此代码是否会重新连接? –

0

是在setInterval的& setTimeout的是asyncronous,但你不能做一个推,你做一个拉,如果你想推读请求的网络套接字

+0

我不能在我的情况下使用websockets,因为我不使用框架。我的网站一直在重新加载。 –