如何使函数等到对象的值未定义为js setTimeout

时间:2016-05-28 11:22:02

标签: javascript settimeout intervals

我需要停止一个函数继续进行,直到我的php脚本从一个需要一点时间加载的文件中获取内容。加载后,我会在我的JavaScript文件中更新保存此信息的对象:var setData = seoApp.siteData.result.wordCount;

我创建了一个根据wordCount的结果更新我的html元素的函数。

我希望我的脚本能够每隔几秒钟检查var setData是否未定义,等待脚本加载setData。我以为我可以使用此代码使用setTimeout执行此操作:

for (var i = 0; i < 10; i++) {
    setTimeout(function () {
      console.log(i);
      if(setData !== undefined){
        // stops the loop from running again
        i =  11
        //run if statements here.
      }else {

      }
    }, 6000);
  }

那不行。它会等待几秒钟然后触发for循环,而不会等到下一个循环直到6秒。

我做错了什么,这是解决这个问题的最好方法吗?

按要求使用php脚本来抓取数据:

<?php

$url = $_GET["url"];
$string = $_GET["keywords"];


  libxml_use_internal_errors(true); //Prevents Warnings, remove if desired
  $content = file_get_contents($url);
  $explodedContent = explode("<title>", $content);
  $explodedExplodedContent = explode("</title>", $explodedContent[1]);

  $explodedBody = explode("<body>", $content);
  $explodedExplodedBody = explode("</body>", $explodedBody[0]);

  echo "{ \"result\": ". "{ ";
  echo "\"titleCount\": " . substr_count($explodedExplodedContent[0], $string) . ", "; // title of that page.
  echo "\"bodyCount\": " . substr_count(strip_tags($explodedExplodedBody[0]), $string);
  echo " } }";
?>

提前致谢!

1 个答案:

答案 0 :(得分:0)

您可能已经使用了XMLHttpRequest对象的回调函数,在该函数中将setData设置为PHP脚本返回的JSON输出。这也是您应该开始进一步处理的地方:

xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        var setData = JSON.parse(xmlhttp.responseText);
        process(setData);
    }
};

// ...

function process(setData) {
    // Here you can do what you need to do with `setData`
}

如果您想在尚未返回数据时执行某些操作,请使用setInterval

var myInterval = setInterval(function () {
     console.log('still waiting...');
}, 6000);

...并在获得数据后清除该间隔。但是您可以根据返回的请求轻松完成(这比检查setData是否undefined更好):

function process(setData) {
    clearInterval(myInterval);
    // Here you can do what you need to do with `setData`
}

您的代码无效的原因是您的for循环同时创建了10个超时,这些都在6秒后一起过期。如果你将setTimeout赋予的函数命名并在第一次超时到期时将该函数传递给新的setTimeout,那将会有效:

setTimeout(function repeatTimeout() {
    console.log(i);
    if(setData !== undefined){
        // stops the loop from running again
        i =  11
        //run if statements here.
    } else {
        setTimeout(repeatTimeout, 6000);
    }
}, 6000);

...但setIntervalclearInterval结合使用会更直接。

附录

This fiddle包含基于您在小提琴中呈现的代码的代码,以及有关更改位置的注释。