是否可以阻止Node JS中的父线程?

时间:2013-04-17 07:29:16

标签: node.js coffeescript hubot

我正在尝试修复一些第三方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.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中,这种性质的问题(有效地是事件驱动的繁忙循环)的规范方法是什么?

1 个答案:

答案 0 :(得分:1)

我假设build是一个字符串。如果是这样,它将是mapBuildTypeIdToName中您期望的值,因为它是一个原语并且它们是按值传递的。

然而,在回调中,您正在引用在循环外声明的构建变量,因此它的状态将是调用回调时变量所处的状态。在你的情况下,回调在循环结束后被调用,所以它是build2。

要获得您要查找的结果,请查看异步库中的eachSeries API。它允许您在数组上运行一系列异步API调用,就好像它们是同步的一样,而不会实际阻塞该线程。