如何推迟路由器的响应?

时间:2015-12-08 07:36:59

标签: node.js promise sequelize.js

我想用sequelize orm从多个表中收集数据。这是我的代码

var recs = [];

models.Data.findAll({
    where: {
        //exchange_id: req.params.exchangeId
        exchange_id: 7
    }
})
.then(function (data) {
    var rec = {};

    data.forEach(function (item, i) {
        console.log('\n data id is ', data[i].id);

        models.ExchangeTable.findOne({
            data_id: data[i].id
        }).then(function (exchangeTable) {
            models.Country_Money.findOne({
                id: exchangeTable.country_money_id
            }).then(function (countryMoney) {
                rec.countryMoneyId = countryMoney.id;
                rec.data = data[i];
            });
        });
    });

    recs.push(rec);
    res.json(recs);
});

,输出为:

Executing (default): SELECT "id", "sell", "buy", "exchange_id", "createdAt", "up
datedAt" FROM "Data" AS "Data" WHERE "Data"."exchange_id" = 7;

 data id is  185

 data id is  186
Executing (default): SELECT "id", "data_id", "country_money_id", "createdAt", "u
pdatedAt" FROM "ExchangeTables" AS "ExchangeTable" LIMIT 1;
GET /ServiceProviders/Exchange/table/5 200 60.349 ms - 4
Executing (default): SELECT "id", "data_id", "country_money_id", "createdAt", "u
pdatedAt" FROM "ExchangeTables" AS "ExchangeTable" LIMIT 1;
Executing (default): SELECT "id", "Country_id", "Money_id" FROM "Country_Money"
AS "Country_Money" LIMIT 1;
Executing (default): SELECT "id", "Country_id", "Money_id" FROM "Country_Money"
AS "Country_Money" LIMIT 1;

我的问题是我不知道如何在循环块中使用延迟,因为where模型的Country_Money条件必须在Data模型中提供预期值。< / p>

请告诉我,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

在使用forEach发送回复之前,您没有等待res#json内创建的承诺完成。虽然数据库查找可能需要一些时间才能异步执行,因此 forEach之后的代码的执行不会等待它们完成。为了使它们等待,我们可以用forEach进行交易,以便将迭代器中的每个承诺映射到一个承诺:

var promises = data.map(function (item, i) {
    console.log('\n data id is ', data[i].id);

    // We must return a value here
    return models
        .ExchangeTable
        .findOne({data_id: data[i].id})
        .then(function (exchangeTable) {

            // Every promise we create must be returned so that
            // its parent waits for it to resolve before giving
            // control to the next `then`
            return models
                .Country_Money
                .findOne({id: exchangeTable.country_money_id})
                .then(function (countryMoney) {

                    // Return an object literal with the data we want
                    // instead of affecting an external store.
                    // This will be the final value for an iteration
                    // and available as a member of the array result of `Promise.all`
                    return {
                        countryMoneyId: countryMoney.id,
                        data: data[i]
                    };
                });
            });
        });

这将产生一系列可以传递给Promise#all的承诺。最后,依赖于每个承诺的代码必须放在then之后的Promise#all内。

return Promise
    .all(promises)
    .then(function (recs) {
        // Here we receive the final result of each
        // promise returned within `data.map` as an array
        res.json(recs);
    });

使用此方法,我们不再需要维护var recs = [];var rec = {};。看看Array.prototype.map的目的和行为,了解其原因。