Node.js:使用回调或异步的值调用函数 [英] Node.js : Call function using value from callback or async
问题描述
我写了下面的.js文件来调用下面定义的函数。
objectRepositoryLoader.readObjectRepository()
返回一个hashmap从哪里必须使用 enterUserName(),enterPassword(),clickLoginButton )
函数。
var path = require('path');
var elementRepoMap = {}
var LandingPage = function(){
var fileName = path.basename(module.filename,path.extname(module.filename))
objectRepositoryLoader.readObjectRepository(fileName +'。xml',function(elementRepo){
console.log(elementRepo)//这里打印的值
this.elementRepoMap = elementRepo
});
this.enterUserName = function(value){
console.log(elementRepoMap)//这里不打印值
//有些代码
};
this.enterPassword = function(value){
//有些代码
};
this.clickLoginButton = function(){
//有些代码
};
};
module.exports = new LandingPage();
objectRepositoryLoader.readObjectRepository()
在另一个文件如下:
var ObjectRepositoryLoader = function(){
this.readObjectRepository = function(fileName,callback){
var filePath ='./elementRepository/'+fileName;
this.loadedMap = this.objectRepoLoader(filePath,function(loadedMap){
return callback(loadedMap);
});
}
this.objectRepoLoader = function(filePath,callback){
if(filePath.includes(。xml)){
this.xmlObjectRepositoryLoader ,function(loadedMap){
return callback(loadedMap);
});
}
this.xmlObjectRepositoryLoader = function(xmlPath,callback){
var innerMap = {};
var elementName;
fs.readFile(xmlPath,utf-8,function(err,data){
if(err){
console.log('File not found !!')
}
else {
var doc = domparser.parseFromString(data,text / xml);
var elements = doc.getElementsByTagName(A1);
(var i = 0; i var elm = elements [i];
elementName = elm.getAttribute(name);
var params = elm .getElementsByTagName(AS);
innerMap = {};
for(var j = 0; j< params.length; j ++){
var param = params [j];
var locatorType = param.getAttribute(type);
var locatorValue = param.getAttribute(value);
innerMap [locatorType] = locatorValue;
}
loadedMap [elementName] = innerMap;
innerMap = {};
};
}
return callback(loadedMap);
});
};我如何调用 enterUserName(),enterPassword(),clickLoginButton(),如下图所示:
< 函数从spec.js文件,并有任何方式,我可以避免使用回调
并使用 async.js
并从spec.js文件调用 enterUserName(),enterPassword(),clickLoginButton()
?
EDIT
我已如下修改我的文件:
this.xmlObjectRepositoryLoader = function (xmlPath){
var innerMap = {};
var elementName;
var filePath = xmlPath +'。xml'
var self = this
return new Promise(
function(resolve,reject){
console.log(In xmlObjectRepositoryLoader :+ filePath)
self.readFilePromisified(filePath)
.then(text => {
var doc = domparser.parseFromString(text,text / xml);
var elements = doc.getElementsByTagName(Element);
for(var i = 0; i var elm = elements [i];
elementName = elm.getAttribute(name);
var params = elm.getElementsByTagName(param);
innerMap = {};
for(var j = 0; j < length; j ++){
var param = params [j];
var locatorType = param.getAttribute(type);
var locatorValue = param.getAttribute(value);
innerMap [locatorType] = locatorValue;
}
map [elementName] = innerMap;
innerMap = {};
}
console.log(map)//打印地图
resolve(text)
})
.catch(error => {
reject(error)
});
});
}
this.readFilePromisified = function(filename){
console.log(In readFilePromisified:+ filename)
return new Promise function(resolve,reject){
fs.readFile(filename,{encoding:'utf8'},
(error,data)=> {
if(error){
拒绝(错误);
} else {
resolve(data);
}
})
})
}
我从另一个文件调用上述函数,如下所示:
objectRepositoryLoader.readObjectRepository(fileName)
.then(text => {
console.log(text);
})
.catch error => {
console.log(error);
});
但它给我的错误是
.then(text => {^
$在这种情况下,我如何使用promise调用另一个promise函数,然后在一个更多的promise函数中使用返回的值,并返回计算的值到调用函数,我可以使用请帮助
TypeError:无法读取未定义的属性'then'
解决方案您可以使用async.waterfall和
async.parallel
可执行此任务
请参阅参考
我刚刚尝试过您的代码使其工作,我在评论中解释了实现方式。
async.waterfall([
function(next){
objectRepositoryLoader.readObjectRepository(fileName +'。xml',next) // pass this next as this function defination and after manipulation return result with callback like this(null,result)
}
],function(err,result){
if(!err){
// Do wahtever你想要的结果
async.parallel([
function(callback){
this .enterUserName = function(value){
console.log(elementRepoMap)
//有些代码
};
},
function(callback){
this.enterPassword = function(value){
// Some Code
};
},
function(callback){
this.clickLoginButton = function(){
// Some Code
};
}
],function(err,results){
//可选回调
};
}
})
I have written below .js file to call below defined function.
objectRepositoryLoader.readObjectRepository()
returns me a hashmap from where i have to use values inenterUserName(), enterPassword(), clickLoginButton()
functions.var path = require('path'); var elementRepoMap = {} var LandingPage = function(){ var fileName = path.basename(module.filename, path.extname(module.filename)) objectRepositoryLoader.readObjectRepository(fileName+'.xml' , function(elementRepo){ console.log(elementRepo) //values are being printed here this.elementRepoMap = elementRepo }); this.enterUserName = function(value){ console.log(elementRepoMap) //values are not being printed here //Some Code }; this.enterPassword = function(value){ //Some Code }; this.clickLoginButton = function(){ //Some Code }; }; module.exports = new LandingPage();
The
objectRepositoryLoader.readObjectRepository()
function defined in another file is as below:var ObjectRepositoryLoader = function() { this.readObjectRepository = function(fileName, callback) { var filePath = './elementRepository/'+fileName; this.loadedMap = this.objectRepoLoader(filePath, function(loadedMap){ return callback(loadedMap); }); } this.objectRepoLoader = function(filePath, callback){ if (filePath.includes(".xml")) { this.xmlObjectRepositoryLoader(filePath, function(loadedMap){ return callback(loadedMap); }); } this.xmlObjectRepositoryLoader = function (xmlPath, callback){ var innerMap = {}; var elementName; fs.readFile(xmlPath, "utf-8",function(err, data) { if(err){ console.log('File not found!!') } else{ var doc = domparser.parseFromString(data,"text/xml"); var elements = doc.getElementsByTagName("A1"); for(var i =0 ; i< elements.length;i++){ var elm = elements[i]; elementName = elm.getAttribute("name"); var params = elm.getElementsByTagName("AS"); innerMap = {}; for(var j =0 ; j< params.length;j++){ var param = params[j]; var locatorType = param.getAttribute("type"); var locatorValue = param.getAttribute("value"); innerMap[locatorType] = locatorValue; } loadedMap[elementName] = innerMap; innerMap={}; }; } return callback(loadedMap); }); };
How can I call
enterUserName(), enterPassword(), clickLoginButton()
function from spec.js file and is there any way I can avoid usingcallback
and useasync.js
and callenterUserName(), enterPassword(), clickLoginButton()
from spec.js file ?EDIT I have modified my file like below:
this.xmlObjectRepositoryLoader = function (xmlPath){ var innerMap = {}; var elementName; var filePath = xmlPath+'.xml' var self = this return new Promise( function(resolve, reject){ console.log("In xmlObjectRepositoryLoader : "+filePath) self.readFilePromisified(filePath) .then(text => { var doc = domparser.parseFromString(text,"text/xml"); var elements = doc.getElementsByTagName("Element"); for(var i =0 ; i< elements.length;i++){ var elm = elements[i]; elementName = elm.getAttribute("name"); var params = elm.getElementsByTagName("param"); innerMap = {}; for(var j =0 ; j< params.length;j++){ var param = params[j]; var locatorType = param.getAttribute("type"); var locatorValue = param.getAttribute("value"); innerMap[locatorType] = locatorValue; } map[elementName] = innerMap; innerMap={}; } console.log(map) // prints the map resolve(text) }) .catch(error => { reject(error) }); }); } this.readFilePromisified = function(filename) { console.log("In readFilePromisified : "+filename) return new Promise( function (resolve, reject) { fs.readFile(filename, { encoding: 'utf8' }, (error, data) => { if (error) { reject(error); } else { resolve(data); } }) }) }
I am calling above function from another file as below:
objectRepositoryLoader.readObjectRepository(fileName) .then(text => { console.log(text); }) .catch(error => { console.log(error); });
But it gives me error as
.then(text => { ^ TypeError: Cannot read property 'then' of undefined
In this case how can I use promise to call another promise function and then use the returned value in one more promise function and return calculated value to calling function where I can use the value in other functions. I sound a bit confused. Please help
解决方案You can use async.waterfall and
async.parallel
to perform this tasksee the reference
I just tried your code to make it working, I explained the way of implementation in comment.
async.waterfall([ function(next){ objectRepositoryLoader.readObjectRepository(fileName+'.xml' ,next)//pass this next as parameter in this function defination and after manipulation return result with callback like this(null,result) } ],function(err,result){ if(!err){ //Do wahtever you want with result async.parallel([ function(callback){ this.enterUserName = function(value){ console.log(elementRepoMap) //Some Code }; }, function(callback){ this.enterPassword = function(value){ //Some Code }; }, function(callback){ this.clickLoginButton = function(){ //Some Code }; } ], function(err, results) { // optional callback }; } })
这篇关于Node.js:使用回调或异步的值调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!