如何检查网站是否异步启动?

时间:2014-04-02 10:32:45

标签: javascript node.js asynchronous coffeescript

我现在使用两种方法,第一种方法是通过检查 HTTP GET状态代码响应来检查网站是否已启动:

checkifUp = (host, callback) ->
  host = host.replace("http://", "").replace("/", "")
  options =
    host: "#{host}"
    port: 80
    path: "/"

  req = http.get(options, (res) ->
    callback(res.statusCode.toString())
    req.connection.destroy()
  )
  

Javascript: http://goo.gl/OyekSx

对于第二个,我所做的是从我拥有的一系列网站中选择一个随机网站,并验证(在第一种方法的帮助下)该网站是否已启动。如果是,我想返回该站点作为父方法的返回值(在这种情况下是第二个),但如果不是,我想重新运行该方法,直到它找到阵列中的在线站点。这是我到目前为止所做的:

siteSet = ->
  site_urls = ["sub1.mysite.com", "sub2.mysite.com", "sub3.mysite.com", "sub4.mysite.com", "sub5.mysite.com"]
  random_site = site_urls[Math.floor(Math.random()*site_urls.length)]

  checkifUp "#{random_site}", (code) ->
    if code isnt "200"
      siteSet()
    else
      selected_site = random_site
  selected_site
  

Javascript: http://goo.gl/ydmSiV

显然,这并不是我想要的方式:如果状态代码不是200,那么它确实重新运行了方法,(到目前为止,我们还可以);但是当网站确实在线时会出现问题,因为我不知道如何将 selected_site 变量(在checkifUp调用中声明)作为父级的返回值返回方法(在这种情况下 siteSet())。我需要这样做才能将 siteSet()返回值用作另一个函数的变量:

otherFunc = ->
  theSite = siteSet()
  console.log(theSite)
  

Javascript: http://goo.gl/cmsryJ

并确信它将始终位于此 otherFunc()

中的在线网站网址(字符串)

我对此有两个问题

  1. 我怎样才能完成我想做的事情? (呃,那个显然是嘿嘿)

  2. 我对此并不十分肯定,但据我所知 Javascript / Coffeescript,当从内部调用 siteSet() otherFunc(),(至少在这个“设置”中),otherFunc()不会等到siteSet()返回一个String(这是我想要的结果) 我对么?即使回归问题已经解决,我认为也是如此 将要发生的是当我从内部调用 siteSet() otherFunc()它将使用调用的确切结果,这意味着如果在运行siteSet()时返回另一个调用 自己(因为 random_site 选择不在线) otherFunc()中的“theSite”变量将采用裸函数() 作为价值,我是否正确? (如果是这样的话),如何解决这个问题 其他问题?我想在里面设置“theSite”变量 otherFunc()直到这样的值是我需要的String。

  3. 提前感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

这里的问题不是你正在为你的otherFunc采用同步方法而不是异步方法,让我们来看看这个:

   //sorry I prefer use plain js, I'm pretty sure than you will be able to understand the code
   var funA = function(){
   //long computation here
    console.log("calling from funA");

   }

 var funB = function(){
    var resultA = funA();
    console.log("resultA is " + resultA);
    console.log("calling from funB");

  }

  funB()

结果将是这样的:

     resultA is undefined
     calling from funB
     calling from funA

您的代码将转换为:

  //sorry I'm not so familiar with coffeescript so maybe I would do a little mistake
  siteSet = (callback)->
    site_urls = ["sub1.mysite.com", "sub2.mysite.com", "sub3.mysite.com",           "sub4.mysite.com", "sub5.mysite.com"]
    random_site = site_urls[Math.floor(Math.random()*site_urls.length)]

    checkifUp "#{random_site}", (code) ->
      if code isnt "200"
         siteSet()
      else
      selected_site = random_site

      callback(selected_site)


   otherFunc = ->
       siteSet((result)-> console.log(result))  //(result)-> console.log(result) is your
                                            //callback, so inside checkifUp you will call it and pass selected_site
                                            //

为了更好地理解为什么nodejs以这种方式执行代码,请查看这些文章...

http://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks

http://dreamerslab.com/blog/en/javascript-callbacks/

    x = LONGIO()
    console.log(x)

    vs

    LONGIO((resultOfLongIO)-> console.log(resultOfLongIO))

基本上异步代码中的想法(没有承诺,生成器,monad或其他)比你将functionA的结果传递给回调......这就是...

答案 1 :(得分:0)

我不太了解CoffeeScript,所以我使用了javascript转换功能来实现两个功能。如果CoffeeScript中有我不知道的特质,请告诉我。

也就是说,看起来你正在使用异步函数siteSet,并试图同步返回一个值。您可以查看this question的解决方案以获取更多信息。您有两种有效返回值的选项:

  • 活动
  • 回调

你的第一个函数checkIfUp有一个回调,所以我的建议也是使用一个用于siteSet。您可以按如下方式调用:

otherFunc = ->
  theSite = siteSet ( theSite ) ->
    console.log(theSite)

至少,我认为这是CoffeeScript的语法。在JavaScript中,它绝对是:

otherFunc() 
{
  theSite = siteSet( function( theSite )
  {
    console.log( theSite );
  } );
}

答案 2 :(得分:0)

像对checkifUp一样添加对siteSet的回调:

siteSet = (callback) ->
  site_urls = ["sub1.mysite.com", "sub2.mysite.com", "sub3.mysite.com", "sub4.mysite.com", "sub5.mysite.com"]
  random_site = site_urls[Math.floor(Math.random()*site_urls.length)]

  checkifUp "#{random_site}", (code) ->
    if code isnt "200"
      siteSet()
    else
      callback(random_site)

然后你可以这样做:

otherFunc = ->
  siteSet (theSite) ->
    console.log theSite