我是节点的新手,我正在做一个随机练习,回调和异步处理对我来说是新的。在解释如何完成这项任务时,我将不胜感激。
我要做的是根据从Excel电子表格中获取的行创建一个对象,并通过在我的表格中添加/更新它们来单独处理它们。
我遇到的问题,我看到的问题与节点新手很常见,并不了解如何同步处理。
我不明白为什么默认情况下会异步运行,当然大部分时间你都希望在执行另一个操作之前发生某些事情?
我可能没有正确接近这个? 在这种情况下,我从excel数据集中获取一行,因为我循环遍历数据集,我为每一行创建一个对象,其中一部分涉及对另一个函数(getAreaId)进行回调以获取基于该对象的area_id areaCode已通过。在我的控制台日志中,myOrganisation对象始终将areaCode显示为undefined。
当我在回调函数中使用console.log时,我看到显示的是正确的值。将回调返回的值分配给本地对象的最佳方法是什么?
我读过我需要添加一些像async这样的中间件。由于这是我在节点上的第一次尝试,我不想开始潜入添加库或使事情变得更复杂,如果我不需要。
function importData(){
var myDataSet = getExcelData();
var x = getOrganisationCode(function(existingOrgCode){
for (j=0; j<myDataSet.length; j++){
function organisationObj(orgCode, orgName, address1, areaCode){
this.orgCode = orgCode;
this.orgName = orgName;
this.address1 = address1;
//this.areaId = getAreaId(areaCode, function(area_id){ return area_id});
getAreaId(areaCode, function(area_id){ this.areaId = area_id});
}
myOrganisation = new organisationObj(myDataSet[j]['OrgCode'], myDataSet[j]['OrgName'], myDataSet[j]['orgName'], myDataSet[j]['areaCode']);
console.log(myOrganisation)
if(isNewOrg(existingOrgCode.indexOf(myOrganisation.orgCode))){
//doInsert
} else {
//doUpdate
}
}
});
}
function getExcelData(){
//This gets data from an excel spreadsheet
}
function isNewOrg(orgCode){
//Checks if orgCode is not -1 and returns true/false accordingly
}
function getOrganisationCode(callback){
//Do a DB call to return all orgCodes
//SELECT orgCode FROM tOrg
}
function getAreaId(areaCode, callback){
//Do a DB call to return an area id based on the code passed
//SELECT areaId FROM tAreas WHERE areaCode = @input_parameter
}
答案 0 :(得分:1)
每当进行异步调用时,操作都会与当前代码流并行执行。
如果执行异步数据库调用,则程序不会等待数据库完成。这就是使用回调的原因。
你只需告诉数据库:“嘿,给我一个身份证明。当你完成时告诉我。我会同时处理其他一些事情。” 然后你的程序继续并退出getAreaId函数。一段时间后,数据库给你回电“嘿,这是id。”并为回调函数提供id。
organisationObj
--> getAreaId
| --> db call
<-- | |
... |
... |
(callback) <------|
答案 1 :(得分:1)
Rita Saxena已经分享了一个很好的链接来解释异步。
代码中的主要问题是循环中存在异步调用getAreaId。
了解async概念的更一般解释(作为Riya Saxena共享的补充),想想这个函数
for(var i = 1; i <= 5; i++) {
setTimeout(function() {
console.log('Value of i : ' + i);
},100);
}
您可能希望输出为:
Value of i : 1
Value of i : 2
Value of i : 3
Value of i : 4
Value of i : 5
但实际输出是:
Value of i : 6
Value of i : 6
Value of i : 6
Value of i : 6
Value of i : 6
这是因为在评估 setTimeout 时,循环已完成,在循环评估结束时保留 i 的值。
此示例可以通过不回答此问题的不同方式进行修复。
在您的情况下,当评估 console.log(myOrganisation)时,
myOrganisation = new organisationObj(myDataSet[j]['OrgCode'],
myDataSet[j]['OrgName'], myDataSet[j]['orgName'],
myDataSet[j]['areaCode']);
尚未从评估中返回(db call)
作为一般准则,在混合循环和异步调用时要小心。