for循环后的Node.js回调

时间:2016-12-05 01:44:27

标签: javascript node.js asynchronous

我是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,但控制台似乎只是永远挂起。

1 个答案:

答案 0 :(得分:0)

for look的一次​​迭代,它不会等到回调在开始下一次之前解决。因此,在任何请求完成之前,可能会完成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