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

时间:2016-03-08 21:25:04

标签: javascript node.js twitter promise sequelize.js

我是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函数来进行查询,但问题仍然存在。

1 个答案:

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