Sequelize JS节点使用先前承诺的新数据更新多个实体
Sequelize JS node updating multiple entities with new data from previous promise
我对 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 函数来进行查询,但问题仍然存在。
不要在承诺中嵌套承诺。相反,通过返回承诺来链接它们。如果您返回的不是承诺,请使用 Promise.resolve(value) 将其转换为承诺。当然不要将 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)
});
我对 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 函数来进行查询,但问题仍然存在。
不要在承诺中嵌套承诺。相反,通过返回承诺来链接它们。如果您返回的不是承诺,请使用 Promise.resolve(value) 将其转换为承诺。当然不要将 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)
});