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