如何在路由器中延迟响应?
How to deferred response in router?
我想使用 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;
我的问题是我不知道如何在循环块中使用延迟,因为给 Country_Money
模型的 where
条件提供了 Data
模型中必须提供的预期值.
请告诉我,我该如何解决这个问题?
在使用 res#json
发送响应之前,您没有等待在 forEach
中创建的承诺完成。虽然数据库查找可能需要一些时间,但它们是异步执行的,因此代码 after 的执行不会等待 forEach
完成。为了让它们 wait 我们可以换取 forEach
将迭代器中的每个 promise 映射到一个 promise:
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
的承诺。最后,依赖于每个承诺的代码必须放在 Promise#all
之后的 then
内。
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
的目的和行为,了解为什么会这样。
我想使用 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;
我的问题是我不知道如何在循环块中使用延迟,因为给 Country_Money
模型的 where
条件提供了 Data
模型中必须提供的预期值.
请告诉我,我该如何解决这个问题?
在使用 res#json
发送响应之前,您没有等待在 forEach
中创建的承诺完成。虽然数据库查找可能需要一些时间,但它们是异步执行的,因此代码 after 的执行不会等待 forEach
完成。为了让它们 wait 我们可以换取 forEach
将迭代器中的每个 promise 映射到一个 promise:
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
的承诺。最后,依赖于每个承诺的代码必须放在 Promise#all
之后的 then
内。
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
的目的和行为,了解为什么会这样。