【问题标题】:Node.js callback after for loopfor 循环后的 Node.js 回调
【发布时间】:2016-12-05 01:44:26
【问题描述】:

我是 Node 新手,我正在尝试在 API 调用的 for 循环中附加数据,但我遇到了 Node 的异步特性的挑战。

function emotionsAPI(data, next){
    for(var url in data) {
        if(data.hasOwnProperty(url)) {
            request({
            method: 'POST',
            url: 'https://api.projectoxford.ai/emotion/v1.0/recognize',
            headers: {
                "Content-Type": 'application/json',
                "Ocp-Apim-Subscription-Key": keys.emotion_key
            },
            body: "{\"url\" : \"" + url + "\"}"
            }, function (error, response, body){
                var emotions = JSON.parse(body)
                if (emotions.length > 0){
                    var scores = emotions[0].scores;
                    console.log("scores found");
                    console.log(scores.anger);
                    data[url].anger = scores.anger;
                }
            })
        }
    }
    next(data);
}

function faceAPI(data){
    console.log("HELP");
    console.log(data);
}

emotionsAPI(data, faceAPI);

faceAPI 函数中的 console.log 正确打印到控制台,但没有反映 for 循环应该进行的更改。我尝试使用 async.forEachOf 但控制台似乎永远挂起。

【问题讨论】:

  • 您正在尝试以异步方法更改数据。他们以不同的方式。也许你应该把“next(data)”方法放在url请求的回调方法中。

标签: javascript node.js asynchronous


【解决方案1】:

我相信您尝试将调用 url 请求作为同步方式,但正如您所提到的,结果是异步的。

我相信这个库对你有好处:async

此外,您可以将方法编写为递归样式。但这不是一个好习惯。您应该将此方法更改为立即调用,然后在回调 post 方法中传递 faceAPI(data) 方法。

【讨论】:

    【解决方案2】:

    for 查找的一次迭代,它不会等到回调解决后再开始下一次。因此,可能在任何请求完成之前完成 forloop 并返回到 next 函数。

    如果您对一个接一个发生的调用感到满意,您可以将它们放在递归函数中,并在前一个请求完成后发出下一个请求。

    var arr = Object.keys(data); // store the key names in an array
    
    emotionsAPI(0, data, faceAPI)
    
    function emotionsAPI(data, index, next) {
      if(index < arr.length) {
        request({
          method: 'POST',
          url: 'https://api.projectoxford.ai/emotion/v1.0/recognize',
          headers: {
            "Content-Type": 'application/json',
            "Ocp-Apim-Subscription-Key": keys.emotion_key
          },
          body: "{\"url\" : \"" + url + "\"}"
        }, function (error, response, body){
          var emotions = JSON.parse(body)
          if (emotions.length > 0){
            var scores = emotions[0].scores;
            console.log("scores found");
            console.log(scores.anger);
            data[arr[index]].anger = scores.anger;
          }
          emotionsAPI(data, ++index, next);
        })
      } else {
        next(data);
      }
    }
    

    否则,如果您希望仍然同时提出请求,我建议您查看Promises。特别是Promise.all

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 2018-01-20
      • 2017-12-11
      • 2015-12-06
      相关资源
      最近更新 更多