【发布时间】:2013-04-17 16:49:22
【问题描述】:
我正在尝试修复一些第三方 NodeJS(hubot 脚本,如果有人关心的话)。这里的想法是,对于从先前调用返回的每个构建,我们都会与 Teamcity REST API 联系一次,并对其进行迭代,打印一条消息。
mapBuildTypeIdToName = (msg, id, callback) ->
url = "http://#{hostname}/httpAuth/app/rest/buildTypes/id:#{id}"
msg.http(url)
.headers(getAuthHeader())
.get() (err, res, body) ->
err = body unless res.statusCode = 200
buildName = JSON.parse(body).name unless err
callback err, msg, buildName
createAndPublishBuildMap = (builds, msg) ->
for build in builds
console.log "foo"
console.log build
mapBuildTypeIdToName msg, build['buildTypeId'], (err, msg, name)->
console.log "bar"
console.log build
baseMessage = "##{build.number} of #{name} #{build.webUrl}"
if build.running
status = if build.status == "SUCCESS" then "**Winning**" else "__FAILING__"
message = "#{status} #{build.percentageComplete}% Complete :: #{baseMessage}"
else
status = if build.status == "SUCCESS" then "OK!" else "__FAILED__"
message = "#{status} :: #{baseMessage}"
msg.send message
问题如下:在for循环开始时,builds有多个对象。这些被迭代,然后进入回调,从而打印出最后一次构建 builds.length 次。
服务器日志如下所示:
foo
build1
foo
build2
bar
build2
bar
build2
虽然预期/期望的行为是:
foo
build1
bar
build1
foo
build2
bar
build2
所以我有两个问题:
1) 为什么会出现这种情况?我知道 Node JS 的非阻塞特性导致主线程(for 循环)执行得比它的非阻塞子线程(mapBuildTypeIdToName)更快。为什么它仍然不使用正确的值调用嵌套函数?为什么只调用最后一个值?
2) 我该如何解决这个问题?如何阻止父线程并等待回调,否则,Node JS 中这种性质的问题(实际上是事件驱动的繁忙循环)的规范方法是什么?
【问题讨论】:
-
你不应该试图阻塞主线程。 Node.js 与线程无关。该应用程序在单线程上运行,并使用基于事件循环的架构。
标签: node.js coffeescript hubot