麻烦在nodejs脚本中使用promises for循环

时间:2018-01-17 13:29:24

标签: javascript node.js promise

我在节点脚本中的for循环中使用promises面临一个小问题

我首先从推特搜索中调用数据,我想在将结果发送到我的应用程序的前端之前将所有推文从英语翻译成法语。似乎我当前的模型不能作为promises.all()console.log('所有PROMISES DONE')在触发T.get()函数时从strart开始。有什么建议吗?

var Twit = require('twit')
var T = new Twit({
  consumer_key: '...',  
  consumer_secret: '...',
  access_token: '...',  
  access_token_secret: '...',
  timeout_ms:           60*1000,  // optional HTTP request timeout to apply to all requests. 
})

//TWITTER
app.post('/twitter/search/hashtags', function (req, res) {

  // TWITTER QUERY PARAMS
  var params = {
    q: req.body.search,
    count: 2,
    //lang: 'fr'
  }

  //GData
  var bloc = [];
  var promises = [];

  // TWITTER API GET INFORMATION
  T.get('search/tweets', params, function(err, data, response) {
      // if there no errors
        if (!err) {
            //PROCESSING DATA FROM TWITTER

            if(data){

              for(var i= 0; i < data.statuses.length; i++){
                //translate all text string which are not in french
                var lang = data.statuses[i].lang;
                var str = data.statuses[i].text;
                if(lang != "fr"){
                  promises.push(translate_str(data.statuses[i].user.screen_name, str, lang));
                }
              }
            }
            //res.send(bloc);

        }
        // if unable to Search a tweet
        else {
          console.log('Something went wrong while SEARCHING...');
          console.log(err);
        }
    }); 

    Promise.all(promises)    
     .then(function(data){ console.log("ALL PROMISES DONE"); console.log(data);/* do stuff when success */ })
     .catch(function(err){ /* error handling */ });

    //TRANSLATE
    function translate_str(name, str, lang){
      return new Promise(function(resolve, reject){
        translate(str, {from: lang, to: 'fr'}).then(res => {
            console.log('TRANSLATED INTO :');
            console.log(res.text);

            //SENTIMENT ANALYSIS
            var r1 = sentiment(res.text, 'fr');
            console.log(r1.score);
            console.log(r1.positive);
            //IF SCORE POSITIVE THEN PUSH TO FRONT
            if(r1.score > 0){
              resolve({
                name: name,
                text: res.text,
                lang: lang,
                selected: false
              })
            }
        }).catch(err => {
            console.error(err);
        });
      })

    }

})

2 个答案:

答案 0 :(得分:1)

发生的事情很简单就是T.get是一个异步函数,它在完成后调用回调,但是Promise.all部分在函数之外,因此它被调用之后当尚未调用回调时,将触发T.get()。尝试在回调中移动它:

T.get('search/tweets', params, function(err, data, response) {
  // if there no errors
    if (!err) {
        //PROCESSING DATA FROM TWITTER

        if(data){

          for(var i= 0; i < data.statuses.length; i++){
            //translate all text string which are not in french
            var lang = data.statuses[i].lang;
            var str = data.statuses[i].text;
            if(lang != "fr"){
              promises.push(translate_str(data.statuses[i].user.screen_name, str, lang));
            }
          }
          Promise.all(promises)    
            .then(function(data){ console.log("ALL PROMISES DONE"); console.log(data);/* do stuff when success */ })
            .catch(function(err){ /* error handling */ });
          }
        }
        //res.send(bloc);
    // if unable to Search a tweet
    else {
      console.log('Something went wrong while SEARCHING...');
      console.log(err);
    }
});

答案 1 :(得分:0)

您提交了ajax请求,然后您的程序在等待它时会跳转到promise.all()并处理但是没有承诺,所以它立即发生。您需要在回调中移动promise函数或使用T.get()。then(),如下所示:

// TWITTER API GET INFORMATION
T.get('search/tweets', params)
.then(data => {
    for (var i = 0; i < data.statuses.length; i++) {
        //translate all text string which are not in french
        var lang = data.statuses[i].lang;
        var str = data.statuses[i].text;
        if (lang != "fr") {
            promises.push(translate_str(data.statuses[i].user.screen_name, str, lang));
        }
    }
    //res.send(bloc);
    Promise.all(promises)
        .then(function (data) { console.log("ALL PROMISES DONE"); console.log(data);/* do stuff when success */ })
        .catch(function (err) { /* error handling */ });
}).catch(err => {
    console.log('Something went wrong while SEARCHING...');
    console.log(err);
});