我现在使用两种方法,第一种方法是通过检查 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()
中的在线网站网址(字符串)我对此有两个问题:
我怎样才能完成我想做的事情? (呃,那个显然是嘿嘿)
我对此并不十分肯定,但据我所知 Javascript / Coffeescript,当从内部调用 siteSet()时 otherFunc(),(至少在这个“设置”中),otherFunc()不会等到siteSet()返回一个String(这是我想要的结果) 我对么?即使回归问题已经解决,我认为也是如此 将要发生的是当我从内部调用 siteSet()时 otherFunc()它将使用调用的确切结果,这意味着如果在运行siteSet()时返回另一个调用 自己(因为 random_site 选择不在线) otherFunc()中的“theSite”变量将采用裸函数() 作为价值,我是否正确? (如果是这样的话),如何解决这个问题 其他问题?我想在里面设置“theSite”变量 otherFunc()直到这样的值是我需要的String。
提前感谢您的帮助。
答案 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