JavaScript有许多小窍门来使编程更加容易。
其中之一就是eval()函数,这个函数可以把一个字符串当作一个JavaScript表达式一样去执行它。前段时间项目中就用到了这个技术,巧妙的解决了问题。
项目中用到这样的技术:在本页用js拉取一个接口、告诉接口回调函数名、接口的回包里直接调用这个函数。这样一来,回调函数的调用,就全交给接口写的回包里做了。
页面js如下
main()
{
$.getScript('http://qiangblog.com/someInterface?callback=bk_someInterface');
}
function bk_someInterface( _return_obj )
{
//这里是回调函数,处理 _return_obj 数据
...
...
}
someInterface的回包如下
var return_obj={
“retcode”:”200”,
“msg”:”Query userid success!”,
“username”:”xiaoqiang”
};if(typeof bk_someInterface==’function’) bk_someInterface(return_obj);
这样做比较方便,回调函数名由调用的函数给接口,接口的回包照写函数名就行了。可是这里也会遇到一些问题,如果这个接口在同一页面需要同时多次调用,那么回调函数则会异步执行。在这种情况下,回调函数就不知道当前的回包数据对应的哪次请求了。以前的解决办法是多给接口一个参数,回包的时候照写就行了。这样,需要修改一下接口程序。
以前的解决办法:
main()
{
var extraParameter = Math.random();
$.getScript('http://qiangblog.com/someInterface?callback=bk_someInterface&extra=' extraParameter);
}
function bk_someInterface( _return_obj )
{
//这里是回调函数,处理 _return_obj 数据
...
...
}
var return_obj={
"retcode":"200",
"msg":"Query userid success!",
"extra":"0.1155661893165",
"username":"xiaoqiang"
};if(typeof bk_someInterface=='function') bk_someInterface(return_obj);
如上,这样写需要改动接口程序,以前接口都是自己用自己写,加个参数之类的改动很方便,但不是所有的项目接口都是自己这边写,前段时间做项目就遇到这个情况,研究了下解决办法。以用JS里的eval动态创建函数来解决。
思路是这样的,既然回包里固定了调用回调函数的格式,即 callbackfunctionname(return_obj),那么改动就必须在其他地方完成。最终我需要回包里的return_obj对象和一些附加参数。那么就可以另外定义一个函数,作为新的回调函数,在这个函数里定义附加参数,然后把附加函数和 return_obj 一起传给原先的回调函数。这样就可以解决了。动态定义函数用eval完成即可。
解决办法如下:
main()
{
//自定义的随机附加参数
var extraParameter = Math.random();
//拿一个时间戳
var timestamp = new Date().getTime();
//定义动态函数名,函数名包含这个时间戳,保证不重名
var bkfunctionname = "bk_someInterface_" + timestamp;
//创建这个动态函数,函数里先定义了附加参数,然后调用原来的回调函数。
eval( bkfunctionname + ' = function(retobj){var extra = "'+extraParameter+'";bk_someInterface(retobj, extra);} ');
//所以在拉取接口的时候可以不用写 extraParameter,extraParameter 已经在新的回调中赋值了。
$.getScript('http://qiangblog.com/someInterface?callback='+bkfunctionname);
}
function bk_someInterface( _return_obj, _extra )
{
//这里是回调函数,处理 _return_obj 数据,同时也可以拿到自己定义的 _extra 了
...
...
}