我是sequelize和NodeJS承诺的新手。我的应用程序基本上保存Twitter API的推文,但也需要实时更新一些保存的推文数据,如转推计数或喜欢计数。
但似乎在获取新数据之后,当我试图在我的推文实例上运行所有更新时,没有任何反应。承诺没有通过。
总结一下:我找到了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);
})
编辑:如果您要执行上述代码,我建议您使用此 Twit 来点击Twitter API:https://github.com/ttezel/twit
要获取凭据以获取API,您需要在Twitter上设置应用程序:https://apps.twitter.com/
编辑2:我已经尝试使用事务和纯Sequelize函数来进行查询,但问题仍然存在。
答案 0 :(得分:1)
不要在承诺中嵌套承诺。相反,通过返回承诺来链接它们。如果要返回的东西不是promise,请使用Promise.resolve(value)将其转换为promise。当然,不要将承诺放在回调中,甚至根本不要混合它们;而是创建一个调用操作的promise,然后在回调中解析promise。
这是我试图改写你想要做的事情。您可能需要将第一个包装在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)
});