简体   繁体   English

序列化JS节点使用先前承诺中的新数据更新多个实体

[英]Sequelize JS node updating multiple entities with new data from previous promise

I am new to sequelize and NodeJS promises in general. 我是新手,NodeJS承诺一般。 My app basically saves tweets from the Twitter API, but also needs to update some of the saved tweets' data in realtime, like the Retweet count or the Liked count. 我的应用程序基本上是从Twitter API中保存推文,但是还需要实时更新一些已保存的推文数据,例如Retweet计数或Liked计数。

But it seems like after fetching the new data, when trying to run all the update on my tweet instances, nothing happens. 但是似乎在获取新数据之后,当尝试在我的tweet实例上运行所有更新时,什么都没有发生。 The promise doesn't go through. 诺言没有兑现。

To sum up : I find 100 saved tweets, chain on a callback that fetches their new data from Twitter, and then chain on updating every single 100 tweets with the new data. 综上所述:我发现有100条保存的tweet,链接到从Twitter上获取其新数据的回调中,然后使用新数据更新每100条tweets。 The later update doesn't go through. 更高版本的更新不会通过。

 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); }) 

EDIT : If you want to execute the above code, I'd recommend using this Twit to hit the Twitter API : https://github.com/ttezel/twit 编辑:如果您想执行上面的代码,我建议使用此Twit打Twitter API: https : //github.com/ttezel/twit

To get credentials to hit the API, you will need to set up an app on Twitter though : https://apps.twitter.com/ 要获得凭据以击中API,您需要通过以下方式在Twitter上设置一个应用程序: https : //apps.twitter.com/

EDIT 2 : I already tried to use transactions and pure Sequelize functions to make my queries, but the issue stood still. 编辑2:我已经尝试使用事务和纯Sequelize函数进行查询,但问题仍然存在。

Don't nest promises inside of promises. 不要在承诺中嵌套承诺。 Instead, chain them by returning promises. 相反,通过兑现承诺将它们链接起来。 If you are returning something that is not a promise, use Promise.resolve(value) to turn it into a promise. 如果返回的不是承诺,请使用Promise.resolve(value)将其变成承诺。 And certainly don't put promises inside of callbacks, or even mix them at all; 当然,不要将promise放在回调中,甚至根本不要混合使用它们。 instead create a promise that calls the action, and then in the callback resolve the promise. 而是创建一个调用操作的Promise,然后在回调中解析Promise。

Here's my attempt to rewrite what you're trying to do. 这是我尝试重写您要执行的操作。 You may need to wrap the first in a Promise.resolve to take advantage of returning the new promise: 您可能需要将第一个包装在Promise.resolve中,以利用返回新的Promise的优势:

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)
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM