Strongloop Loopback - 远程方法中的异步函数处理(每个函数内部)
Strongloop Loopback - asynchronous functions handling in remote method (inside for each function)
我正在使用 Loopback 开发 api,我开发了一些远程方法来从传出模块检索数据并根据需要重新排列数据。这是我的示例代码。
mainModule.viewAll = function(cb) {
var mainFilter = {fields: ['f_name', 'l_name', 'id'], where: {status: 1}};
var cEmp = null;
mainModule.find(mainFilter, function(err, mainModules) {
var returnArray = [];
var returnEle;
var secondModule = app.models.secondModule;
mainModules.forEach(emp=>{
returnEle = {};
returnEle['name'] = emp.name;
secondModule.count({ where: { type: 1 }}, function (err, count) {
returnEle['field1'] = count;
console.log(count);
});
secondModule.count({ where: { type: 1 } }, function (err, count) {
returnEle['field2'] = count;
console.log(count);
});
secondModule.count({ where: { type: 1 } }, function (err, count) {
returnEle['field3'] = count;
console.log(count);
});
returnArray.push(returnEle);
});
cb(null, returnArray);
});
};
mainModule.remoteMethod('viewAll', {
'http': {'verb': 'get', 'path': '/viewAll'},
returns: {arg: 'profiles', type: 'Array'},
});
而我的回复是这样的,
{
"profiles":[
{
"name":"Jhone",
"id":1
},
{
"name":"Shaam",
"id":2
},
{
"name":"Viki",
"id":3
}
]
}
正如您在此处看到的,它仅响应名称和 ID 字段,没有关于 'filed1'、'field2'、'field3' 的详细信息。但在控制台日志中 'field1'、'field2','field3'显示完美。
我发现原因可能是 JavaScript 的异步行为。我研究了一些解决此问题的方法,例如使用回调函数,Promise etc. but none of those are fit with situation. (Promises 接缝效率更高,因此我尝试将第二个模块函数与一个 promise 和整个 'for each' 函数包装到另一个 promise 和 cb(null, returnArray);
被设置为 then 函数。但它也没有用)。
我是环回的新手,所以如果有人知道答案请帮助我。
使用 async.eachOf 对每个模块应用异步操作,然后对于每个模块,使用 async.parallel 并行计算您的 3 计数:
var returnArray = [];
async.eachOf(mainModules, function(module, index, acb){
// for each module do parallel count
async.parallel({
field1: function(pcb){
secondModule.count({ where: { type: 1 }}, pcb);
},
field2: function(pcb){
secondModule.count({ where: { type: 1 } }, pcb);
},
field3: function(pcb){
secondModule.count({ where: { type: 1 } }, pcb);
}
}, function(err, result){
// final parallel callback, when all parallel count are finished
if(err || !result)
{
return acb(err || true);
}
else
{
result.name = module.name;
// here result contains the 3 count in result["field1"], result["field2"] and result["field3"]
returnArray.push(result);
return acb(null);
}
})
}, function(err){
// final async.each of callback when all modules are proceed
if(err)
{
// do stg
}
else
{
return cb(null, returnArray)
}
})
我正在使用 Loopback 开发 api,我开发了一些远程方法来从传出模块检索数据并根据需要重新排列数据。这是我的示例代码。
mainModule.viewAll = function(cb) {
var mainFilter = {fields: ['f_name', 'l_name', 'id'], where: {status: 1}};
var cEmp = null;
mainModule.find(mainFilter, function(err, mainModules) {
var returnArray = [];
var returnEle;
var secondModule = app.models.secondModule;
mainModules.forEach(emp=>{
returnEle = {};
returnEle['name'] = emp.name;
secondModule.count({ where: { type: 1 }}, function (err, count) {
returnEle['field1'] = count;
console.log(count);
});
secondModule.count({ where: { type: 1 } }, function (err, count) {
returnEle['field2'] = count;
console.log(count);
});
secondModule.count({ where: { type: 1 } }, function (err, count) {
returnEle['field3'] = count;
console.log(count);
});
returnArray.push(returnEle);
});
cb(null, returnArray);
});
};
mainModule.remoteMethod('viewAll', {
'http': {'verb': 'get', 'path': '/viewAll'},
returns: {arg: 'profiles', type: 'Array'},
});
而我的回复是这样的,
{
"profiles":[
{
"name":"Jhone",
"id":1
},
{
"name":"Shaam",
"id":2
},
{
"name":"Viki",
"id":3
}
]
}
正如您在此处看到的,它仅响应名称和 ID 字段,没有关于 'filed1'、'field2'、'field3' 的详细信息。但在控制台日志中 'field1'、'field2','field3'显示完美。
我发现原因可能是 JavaScript 的异步行为。我研究了一些解决此问题的方法,例如使用回调函数,Promise etc. but none of those are fit with situation. (Promises 接缝效率更高,因此我尝试将第二个模块函数与一个 promise 和整个 'for each' 函数包装到另一个 promise 和 cb(null, returnArray);
被设置为 then 函数。但它也没有用)。
我是环回的新手,所以如果有人知道答案请帮助我。
使用 async.eachOf 对每个模块应用异步操作,然后对于每个模块,使用 async.parallel 并行计算您的 3 计数:
var returnArray = [];
async.eachOf(mainModules, function(module, index, acb){
// for each module do parallel count
async.parallel({
field1: function(pcb){
secondModule.count({ where: { type: 1 }}, pcb);
},
field2: function(pcb){
secondModule.count({ where: { type: 1 } }, pcb);
},
field3: function(pcb){
secondModule.count({ where: { type: 1 } }, pcb);
}
}, function(err, result){
// final parallel callback, when all parallel count are finished
if(err || !result)
{
return acb(err || true);
}
else
{
result.name = module.name;
// here result contains the 3 count in result["field1"], result["field2"] and result["field3"]
returnArray.push(result);
return acb(null);
}
})
}, function(err){
// final async.each of callback when all modules are proceed
if(err)
{
// do stg
}
else
{
return cb(null, returnArray)
}
})