2016-03-08 30 views
1

我是新来的集合和NodeJS承诺一般。我的应用程序基本上保存Twitter API的推文,但也需要实时更新一些保存的推文数据,例如转推计数或喜欢计数。Sequelize JS节点更新多个实体与前一个承诺的新数据

但是好像在获取新数据后,当试图在我的tweet实例上运行所有更新时,没有任何反应。承诺没有通过。

综上所述:我觉得100个保存的鸣叫,链上从Twitter获取他们的新数据,然后对链条的每一个100米的鸣叫与新的数据更新回调。后面的更新没有通过。

var Sequelize = require('sequelize'); 
 

 
... 
 

 
//Getting 100 tweets previously saved in DB 
 
Sequelize.query("SELECT * FROM tweets WHERE ORDER BY id DESC LIMIT 100", { model: Model }).then(function(result) { 
 

 
    if(result.length == 0) { 
 
     callback(false); 
 
    } else { 
 
     var ids = []; 
 
     var realData = {}; 
 

 
     for (var i in result) { 
 
      realData[result[i].dataValues.id_str] = result[i]; 
 
      ids.push(result[i].dataValues.id_str); 
 
     } 
 

 
     //getting twitter data for 100 tweets previously saved in DB 
 
     twitVendor.get('statuses/lookup', { 
 
      id : ids.join(',') 
 
     }, function (err, tweets, response) { 
 
      if (typeof err == 'undefined') { 
 

 
       //to get a synchronous saving of all tweets 
 
       //this could be cleaned up with a Sequelize.Promise.push(...) 
 
       var i = 0; 
 
       var saving = false; 
 

 
       while (i < tweets.length) { 
 
        if (!saving) { 
 
         saving = true; 
 

 
         console.log('Updating tweet ', tweets[i].id_str); 
 

 
         //updating tweet with new data from twitter 
 
         Sequelize.query("UPDATE tweets SET retweet_count = "+tweets[i].retweet_count+", favorite_count = "+tweets[i].favorite_count+" WHERE id_str = '"+tweets[i].id_str+"'", { 
 
          model: Model 
 
         }).then(function(result) { 
 
          console.log('Updated tweet'); 
 
          saving = false; 
 
          i++; 
 
         }).catch(function (err) { 
 
          console.log('Failed to update post ', err); 
 
          saving = false; 
 
          i++; 
 
         }); 
 
        } 
 
       } 
 

 
       callback(true); 
 
       console.log("Updated tweets"); 
 
      } else { 
 
       console.log("Failed :", err); 
 
       callback(false, err); 
 
      } 
 
     }); 
 
    } 
 
}).catch(function (err) { 
 
    console.log("Failed :", err); 
 
    callback(false, err); 
 
})

编辑:如果要执行上面的代码,我推荐使用这种打Twitter的API:https://github.com/ttezel/twit

要获得凭据点击API,你将需要在Twitter上设置一个应用:https://apps.twitter.com/

编辑2:我已经尝试使用事务和纯序列化函数来提出我的疑问,但问题仍然存在。

回答

1

不要在promise中嵌套promise。相反,通过返回承诺来链接它们。如果您返回的是不是承诺的内容,请使用Promise.resolve(value)将其变为承诺。当然不要在回调中承诺,或者甚至混合它们;而是创建一个调用该动作的承诺,然后在回调中解决承诺。

这是我尝试重写你想要做的事情。您可能需要将第一个包装在Promise.resolve中以利用返回新承诺的优势:

Sequelize.query("SELECT * FROM tweets WHERE ORDER BY id DESC LIMIT 100" 
    , { model: Model }).then(function (results) { 
    if (results.length == 0) { 
     return Promise.reject(false); //reject to hit the catch of the promise. Change false to error. 
    } 
    var ids = []; 
    var realData = {}; 

    for (var i in result) { 
     realData[result[i].dataValues.id_str] = result[i]; 
     ids.push(result[i].dataValues.id_str); 
    } 

    return new Promise((resolve, reject) => { 
     twitVendor.get('status/lookup', { 
      id: ids.join(',') 
     }, function (err, tweets, response) { 
      if (err) { 
       reject(false); //reject to hit the catch of the promise. Change false to error message 
      } 
      resolve(tweets); 
     }) 
    }) 
}).then(function (tweets) { 
    function updateTweet(tweet) { 
     return sequelize.query(...); 
    } 

    var updatesInParallel = tweets.map(updateTweet); 

    return Promise.all([updatesInParallel]); 
}).then(function() { 
    callback(true); 
}).catch(function (error) { 
    console.log("failed: ", error); 
    callback(false) 
}); 
+0

好的,我会花时间重做所有不链接回调的东西。这可能需要一点时间。 –

+0

这就像一个魅力,与最后**然后**通话挣扎了一下,但看起来很完美。非常感谢你 ! –