2016-08-23 93 views
2

我正在尝试调用ajax请求来检查数据库的函数,每隔10秒查看一下我想要的信息是否已经到达,如果所需信息未到达60秒,我只想退出该功能。 我现在遇到的问题是,我的功能每10秒钟不会调用self.startInstantorCheck,然后在60秒后退出到最后。 下面是函数试图让淘汰赛js检查数据是否每10秒来一次

所有的
self.startInstatorCheck = function(){ 
       self.instatorStarts(true); 
       var MAX_WAIT_TIME_MS = 1 * 60 * 1000; 
       var POST_INTERVAL_MS = 10 * 1000; 
       var timeoutTime = null; 
       $.ajax({ 
         type: 'POST', 
         url: BASEURL + 'index.php/moneyexchange/check_instantor_field/' + auth, 
         contentType: 'application/json; charset=utf-8' 
        }) 
       .done(function(userinfo) { 
        if (timeoutTime == null) { 
         // Start of the timeout cycle: 
         timeoutTime = Date.now() + MAX_WAIT_TIME_MS; 
        } 
        if (userinfo.instantor_request > 12) { 
         self.allInstantorCheckMessages('Instantor data gathered'); 
        } else { 
         if (Date.now() < MAX_WAIT_TIME_MS) { 
         setTimeout(self.startInstatorCheck(), POST_INTERVAL_MS); 
         } else { 
          self.allInstantorCheckMessages('Please go through instantor to '); 
          self.instatorStarts(true); 
          self.magicInstantorbtn2(true); 
         } 
        } 
       }) 
       .fail(function(jqXHR, textStatus, errorThrown) { 
        self.errorMessage(errorThrown); 
       }) 
       .always(function(data){    
       }); 
     } 
I am using knockout js, so would be great if the answers or help are related to knockout js. 
+0

你说这不叫每10和60这之后并没有结束?或者它不会每10秒钟呼叫一次,但60秒后它会结束? –

+0

@PatrickMotard我想说的是,它应该调用函数10秒来查看是否获得了instantor_request> 12,并且在60秒后如果没有instantor_request的结果,那么它应该退出函数并执行此步骤 'self.allInstantorCheckMessages('请通过instantor到'); self.instatorStarts(true); self.magicInstantorbtn2(true);' – FaF

+0

对不起,如果我不清楚。我知道你的目标是什么。我要求的是澄清什么不起作用。什么部分不起作用。它在60秒后继续轮询吗?它是否根本不投票? –

回答

2

首先,这里是你的简化,以减少嵌套,并通过命名提供清晰的代码。

  self.startInstatorCheck = function(){ 
       self.instatorStarts(true); 
       var MAX_WAIT_TIME_MS = 1 * 60 * 1000; 
       var POST_INTERVAL_MS = 10 * 1000; 
       var timeoutTime = null; 
       $.ajax({ 
         type: 'POST', 
         url: BASEURL + 'index.php/moneyexchange/check_instantor_field/' + auth, 
         contentType: 'application/json; charset=utf-8' 
        }) 
       .done(function(userinfo) { 
        // please use === not == 
        // == doesn't always do what you want it to do, NEVER use it 
        timeoutTime = timeoutTime === null ? 
         Date.now() + MAX_WAIT_TIME_MS : 
         timeoutTime; 

        var pleaseNameMe = userinfo.instantor_request > 12 
        if (pleaseNameMe) { 
         return self.allInstantorCheckMessages('Instantor data gathered'); 
        } 

        var expired = Date.now() < MAX_WAIT_TIME_MS 
        if (!expired) { 
         return setTimeout(self.startInstatorCheck(), POST_INTERVAL_MS); 
        } 

        self.allInstantorCheckMessages('Please go through instantor to '); 
        self.instatorStarts(true); 
        self.magicInstantorbtn2(true); 

       }) 
       .fail(function(jqXHR, textStatus, errorThrown) { 
        self.errorMessage(errorThrown); 
       }) 
       .always(function(data){    
       }); 
     } 

其次,你的问题已经解决了,knockoutjs与否。 Here is a wonderful article解释如何使用超时在JavaScript中进行轮询。它建议使用承诺。我非常同意。 (他们可以并且应该与knockout js一起使用。)直接来自博客的一个人为的例子:

// The polling function 
function poll(fn, timeout, interval) { 
    var dfd = new Deferred(); 
    var endTime = Number(new Date()) + (timeout || 2000); 
    interval = interval || 100; 

    (function p() { 
      // If the condition is met, we're done! 
      if(fn()) { 
       dfd.resolve(); 
      } 
      // If the condition isn't met but the timeout hasn't elapsed, go again 
      else if (Number(new Date()) < endTime) { 
       setTimeout(p, interval); 
      } 
      // Didn't match and too much time, reject! 
      else { 
       dfd.reject(new Error('timed out for ' + fn + ': ' + arguments)); 
      } 
    })(); 

    return dfd.promise; 
} 

// Usage: ensure element is visible 
poll(function() { 
    return document.getElementById('lightbox').offsetWidth > 0; 
}, 2000, 150); 
+0

我试过你的代码,它没有工作,我不知道为什么,它没有比函数更多地调用函数,它只是检查值是否大于12,并且因为它不存在。 – FaF

+0

我重申您的代码只是清理它。我没有改变它的任何功能。我只是想告诉你一个更清晰的写作方式。下面的例子是您可以用来创建自己的“正确”解决方案的一个例子。我给你的方法是自己解决这个问题,而不是为你解决。 “给一个男人一条鱼,然后你喂他一天,告诉他如何捕鱼,并且你一辈子喂他。” –

+0

是啊,我明白了,但我过去10个小时这样做,我超级紧张和沮丧,会很好,如果你能帮我解决它 – FaF

1

你的代码中几乎没有错误。

比较这与你看到的变化

self.startInstatorCheck = function() { 
    self.instatorStarts(true); 
    var t = new Date(); 
    var timeoutTime = t.setSeconds(t.getSeconds() + 60) 
    var interval = 10 * 1000; 

    function instatorCheck() { 
     $.ajax({ 
       type: 'POST', 
       url: BASEURL + 'index.php/moneyexchange/check_instantor_field/' + auth, 
       contentType: 'application/json; charset=utf-8' 
      }) 
      .done(function(userinfo) { 
       if (userinfo.instantor_request > 12) { 
        self.allInstantorCheckMessages('Instantor data gathered'); 
       } else { 
        if (new Date() < timeoutTime) { 
         setTimeout(instatorCheck, interval); 
        } else { 
         self.allInstantorCheckMessages('Please go through instantor to '); 
         self.instatorStarts(true); 
         self.magicInstantorbtn2(true); 
        } 
       } 
      }) 
      .fail(function(jqXHR, textStatus, errorThrown) { 
       self.errorMessage(errorThrown); 
      }) 
      .always(function(data) {}); 
    } 
    instatorCheck(); 
} 
+0

我可以问你为什么使用两个功能?不能用一个做? – FaF

+0

因为所有本地的'instatorCheck'调用都需要一个全局'timeoutTime'。也会每隔10秒运行一次'instatorCheck',而不是'startInstatorCheck' – Jag

+0

我试过了你的代码,但它不会每10分钟调用一次该函数,或者等待60秒后才能通过instatotor进行,直接直接去那里。 – FaF