Node.js:使用回调或异步的值调用函数 [英] Node.js : Call function using value from callback or async

查看:310
本文介绍了Node.js:使用回调或异步的值调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了下面的.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 => {^ 

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 in enterUserName(), 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 using callback and use async.js and call enterUserName(), 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 task

see 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆