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