鉴于Node的异步特性,我无法弄清楚如何完成我正在尝试的内容。从概念上讲,我想这样做:
这是我的代码:
client.get('search/tweets', {q: 'node.js'}, function(error, tweets, response)
{
for (var i=0; i<tweets.statuses.length; i++){
var ttext = tweets.statuses[i].text;
var tsrc = tweets.statuses[i].source;
var lang = '';
var sentiment = '';
var score = '';
var tweet = {
text: tweets.statuses[i].text,
source: tweets.statuses[i].source
};
alchemyapi.sentiment("text", ttext, {}, function(response) {
if (response.status == 'OK' ){
tweet.lang = response.language;
tweet.sentiment = response['docSentiment'].type;
tweet.score = response['docSentiment'].score;
console.log("pushing: " + util.inspect(tweet) );
tweet_data.push( tweet );
}
});
}
res.render('twitter', {
myText: myText,
});
});
&#13;
正在发生的事情是在任何alchemyapi调用完成之前呈现的页面。我很想思考 异步术语和避风港已经完全绕过它。
非常感谢任何帮助!
谢谢, 安迪
编辑 -
我正在尝试使用Promises实现延迟方法而且没有太多运气..我现在已经将parseTweet定义为您建议的函数,如果响应是&#39; OK&#39;它调用resolve(tweet) - 不确定这是否正在做任何事情。我的for()循环现在看起来像这样:
promises.push(parseTweet(tweets.statuses[i]));
Promise.all(promises).then(function(){
console.log('all promises complete');
}, function(){
console.log('error occurred with promises');
});
&#13;
我在parseTweet函数中有注释,我看到所有的推文都被解析但不在Promise.all块中 - 并且程序永远不会完成,一直运行直到我杀了它......
答案 0 :(得分:1)
好的,函数“alchemyapi.sentiment”是异步的,你正在调用很多次,完全是“tweets.statuses.length”,并且在代码的末尾你调用函数“res.send”所以你在“for loop”结束之前调用此函数,因此,这是我的解决方案(伪代码):
1)创建一个接收推文的函数,创建推文数据(你的逻辑+ alchemyapi.sentiment)。此函数返回一个javascript承诺(在我的示例中,我将使用jquery defer编写更少的代码,但您可以使用本机承诺):
function parseTweet(tweet) {
$promise = $.defer();
var tweetDataObject = {}; // this is not important, put your required data
// call alchemyapi async
alchemyapi.sentiment("text", ttext, {}, function(response) {
if (response.status == 'OK' ) {
// parse data and "return" valid object
$promise.resolve(tweetDataObject);
} else { // data is not valid, return null
$promise.reject(null); // null, empty object, what you need
}
});
return $promise;
}
2)在你的main方法上,执行for循环,调用函数parseTweet(返回类似promise的内容)并等待所有promise:
var promises = [];
for (var i=0; i<tweets.statuses.length; i++) {
promises.push(parseTweet(tweets.statuses[i]));
$.when(promises).then(function() {
// here, on "arguments" you have array of objects that parseTweet "return" when called resolve or reject
console.log(arguments);
});
}
我使用jquery defer编写了这个例子,但是使用本机承诺很容易(特别是在这种情况下,我们有许多承诺等待$ .when函数)。
请仔细阅读这篇文章:http://www.html5rocks.com/en/tutorials/es6/promises/
我在github上做了一个例子。如果您有疑问请告诉我,但我认为这很清楚 https://github.com/josemato/stackoverflow/tree/master/es-promise-all-no-order
答案 1 :(得分:0)
使用vert.x很容易:当请求事件进入时,将其推迟到工作模块并让它执行长时间运行的处理。注册处理“all finished”事件的处理程序以进行显示。
也许这个过程也适用于node.js:让长时间运行的炼金术调用一个单独的线程,在完成后注册“全部完成”事件。要求UI在收到该事件时使用回调注册自己。