js怎样获取调用回调函数的参数值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js怎样获取调用回调函数的参数值相关的知识,希望对你有一定的参考价值。
比如jquery里面的post请求取数据,$.post('post_url',,function(data),'json');里面有一个回调函数,我想把data这个值赋值给一个全局变量,但是赋值了无法都到值,请大牛帮帮忙,指导一下!(请帮我写个简单的例子,谢谢啦)
代码如下:function a(callback)
alert('a');
callback.call(this);//或者是 callback(), callback.apply(this),看个人喜好
function b()
alert('b');
//调用
a(b);
这样的结果是先弹出 'a',再弹出‘b'。这样估计会有人问了“写这样的代码有什么意思呢?好像没太大的作用呢!”
是的,其实我也觉得这样写没啥意思,“如果调用一个函数就直接在函数里面调用它不就行了”。我这只是给大家写个小例子,做初步的理解。真正写代码的过程中很少用这样无参数的,因为在大部分场景中,我们要传递参数。来个带参数的:
复制代码 代码如下:
function c(callback)
alert('c');
callback.call(this,'d');
//调用
c(function(e)
alert(e);
);
这个调用看起来是不是似曾相识,这里e参数被赋值为'd',我们只是简单的赋值为字符窜,其实也可以赋值为对象。Jquery里面是不是也有个e参数,下面我们就来讲讲
Jquery里面的e参数是如何被回调赋值的。
Jquery框架我想大家不陌生了,出来了好久,开发的时候都在用,比较简单,api网上搜起来很方便,上手快。在Jquery框架下,我们有时候要获取事件中的一些参数,比如我要获取当前点击的坐标,点击的元素对象。这个需求在Jquery里面好办 :
复制代码 代码如下:
$("#id").bind('click',function(e)
//e.pageX ,e.pageY ,e.target.....各种数据
);
用起来倒是挺方便,其实这个e参数的赋值也是通过回调函数来实现的,这个参数是用回调参数给它赋予了一个对象值,仔细研究过JJquery源码的朋友应该发现了这一点。
还有Ajax里面 $.get('',,function(data)) data这个参数也是同样的原理。
我们来看看Jquery事件对象里面是怎么应用回调函数的。
为了方便,我简单的写了一下$相关的一些实现,之前写过“小谈Jquery”里面有比较接近框架实现的方法,我下面只是写一个简易的选择器。
复制代码 代码如下:
<div id="container" style="width:200px;height:200px;background-Color:green;">
< /div>
< script>
var _$=function (id)
this.element= document.getElementById(id);
_$.prototype=
bind:function(evt,callback)
var that=this;
if(document.addEventListener)
this.element.addEventListener(evt, function(e)
callback.call(this,that.standadize(e));
,false);
else if(document.attachEvent)
this.element.attachEvent('on'+evt,function(e)
callback.call(this,that.standadize(e));
);
else
this.element['on'+evt]=function(e)
callback.call(this,that.standadize(e));
;
,
standadize:function(e)
var evt=e||window.event;
var pageX,pageY,layerX,layerY;
//pageX 横坐标 pageY纵坐标 layerX点击处位于元素的横坐标 layerY点击处位于元素的纵坐标
if(evt.pageX)
pageX=evt.pageX;
pageY=evt.pageY;
else
pageX=document.body.scrollLeft+evt.clientX-document.body.clientLeft;
pageY=document.body.scrollTop+evt.clientY-document.body.clientLTop;
if(evt.layerX)
layerX=evt.layerX;
layerY=evt.layerY;
else
layerX=evt.offsetX;
layerXY=evt.offsetY;
return
pageX:pageX,
pageY:pageY,
layerX:layerX,
layerY:layerY
window.$=function(id)
return new _$(id);
$('container').bind('click',function(e)
alert(e.pageX);
);
$('container1').bind('click',function(e)
alert(e.pageX);
);
< /script>
这段代码我们主要看standadize函数的实现,兼容性的代码,就不多说了,返回的是一个对象
复制代码 代码如下:
return
pageX:pageX,
pageY:pageY,
layerX:layerX,
layerY:layerY
然后再看bind函数里面的代码 callback.call(this,that.standadize(e)),这段代码其实就是给e参数赋值了,是用callback回调实现的。
callback 函数被调用的时候传入的是匿名函数
复制代码 代码如下:
function(e)
而callback.call(this,that.standadize(e))相当于是执行了这么一段代码
复制代码 代码如下:
(function(e)
)(standadize(e))
这也是Jquery用回调函数比较经典的地方,e参数就是这么被赋值的,说了这些你们也大概有个了解了,以及怎么使用了。
回调在各种框架中应用的比较多,有时候自己写一些东西的时候也可以根据实际情况用用看。 参考技术A 办法你可以自己想,我给你说下你取不到值得原因吧!
首先,JQUERY封装的是ajax,而ajax是异步的,也就是你程序运行到这一步向后台发出请求,后台并不会马上给你返回数据,而是前台继续运行页面上其他的代码。后台在处理完你这个请求之后,才会向前台发送你想要的数据,这个时候返回的data才会给全局变量赋值,而这时候你前台使用全局变量的函数已经运行过了,所以才会出现无法赋值的情况。本回答被提问者和网友采纳 参考技术B 先alert一下data,看弹出来的值是什么
[JS]回调函数和回调地狱
回调函数
小明在奶茶店点了奶茶,店员开始制作奶茶,此时“制作奶茶”与“小明等待奶茶”是一个同时进行的不同的两个事件(任务),那么,小明获取店员制作成功的奶茶是从“制作奶茶”这一事件获取的结果,所以小明才能够完成“购买奶茶”这一事件。如果,小明在“购买奶茶”这一事件中,不想一直等待而是想去做一些其他的事情,比如购买冰淇淋。
现在,我们将这一案例抽取为一个个事件,用 JavaScript 函数体现出来:
// 小明购买奶茶事件
function buyTea() {
console.log(\'购买奶茶...\')
}
// 店员制作奶茶事件
function makeTea() {
console.log(\'制作奶茶...\')
}
// 小明的另一个事件
function buyIcecream() {
console.log(\'购买冰淇淋...\')
}
目前,这些事件属于同步任务(事件),它们被主线程由上到下依次执行,无法在同一时间内执行多个事件。你会发现,这些事件之间是各自独立的。如何将它们有机地、有序地结合在一起是一个问题。
因此,在 JavaScript 中,有一种解决方式叫做异步任务(事件),利用回调函数将这些独立的事件结合在一起。在 JavaScript 中,函数作为第一等公民的存在,可以将函数作为对象传递给方法作为实参进行调用,即回调函数。
请转至“[JS]函数作为值”一文,了解什么函数是如何作为值,并且可以作为函数实参进行传递以及调用的。
function buyThing(money = 0, callback) {
let isPay = false
if (money >= 5) isPay = true
callback(isPay)
}
buyThing(10, function (isPay) {
if (isPay) {
console.log(\'购买奶茶...\')
setTimeout(() => {
console.log(\'奶茶制作完成!!!\')
buyThing(20, function (isPay) {
if (isPay) {
console.log(\'购买冰淇淋...\')
setTimeout(() => {
console.log(\'冰淇淋制作完成!!!\')
buyThing(30, function(isPay) {
// ...做很多事件,多次调用buyThing函数
})
}, 2000)
} else {
console.log(\'未支付金额...\')
}
})
}, 1000)
} else {
console.log(\'未支付金额...\')
}
})
回调函数的确将这些独立事件有机地结合在一起了,但是随之而来的就是回调地狱。
现在,我们明白了回调函数的好处。再列举一个例子,深入了解回调函数的好处在哪。若实现一个简单的计算器,其功能有加、减、乘、除等运算,通常情况下会想到一个函数获得两个参数,并将运算类型作为字符串传递给函数参数以实现不同需求。
function calculate(x, y, type) {
if (type == \'minus\') {
return x - y
} else if (type == \'add\') {
return x + y
} ......
}
let result = calculate(10, 20, \'minus\') // -10
上述代码,存在一个明显的问题。如果在减法中做其他的限制条件(或增加源代码的功能),它会影响到整个 calculate 函数本身。再者,如果我扩展 calculate 函数功能,它也会影响到函数本身。对于这种情况,我们寄希望于回调函数,通过它来解决这个问题。
// calculate本体做一些基本的判断(限制)
function calculate(x, y, callback) {
if (x < 0 || y < 0) {
throw new Error(`Numbers must not be negative!`)
}
if (typeof x !== \'number\' || typeof y !== \'number\') {
throw new Error(`Args must be number type!`)
}
return callback(x, y, \'not problem!!!\') // 向外提供更多细节
}
// 没有做任何附加限制
calculate(10, 20, function (x, y, more) {
console.log(more) // \'not problem!!!\'
return x * y
})
// 做了一些附加限制
calculate(5, 5, function (x, y, more) {
console.log(more) // \'not problem!!!\'
if (x + y <= 10) {
throw new Error(
\'The sum of the two numbers must be greater than 10\'
)
}
return x * y
})
现在,调用 calculate 函数时,可以在回调函数中做一些附加限制条件,它不会影响到 calculate 这个函数本体。并且,回调函数可以从 calculate 函数本体中获取更多的细节(信息),通过这些信息我们又能做出更多的操作。
let points = [40, 100 ,10, 5, 25]
points.sort(function (a, b) => {
return a - b
}) // [5, 10, 25, 40, 100]
// ...另一种比较方式...
points.sort(function (a, b) => {
if (a < b) {
return -1
}
if (a > b) {
return 1
}
return 0
}) // [5, 10, 25, 40, 100]
在回调函数中不同的排序方式可以决定最后的结果。回调函数使得程序更加灵活。
回调地狱
在上面的“小明买奶茶”案例中,回调内部再嵌套回调,其代码形状上看着像180°旋转之后的金字塔,这种层层嵌套就是回调地狱。
因此,Promise 可以解决回调地狱的问题。Promise 是一个对象,用于表示一个异步操作的最终完成(或失败)及其结果值。
利用 Promise 解决“小明买奶茶”回调地狱:
function buyThing(money, timeout) {
const promise = new Promise((resolve, reject) => {
console.log(\'事件正在进行中...\')
setTimeout(() => {
if (money >= 5) {
console.log(`支付金额:${money}`)
resolve(\'success to pay!\')
} else {
reject(\'unsuccess to pay!\')
}
}, timeout)
})
return promise
}
buyThing(10, 1000)
.then((res) => {
console.log(\'奶茶制作完成!!!\')
return buyThing(20, 2000)
})
.then((res) => {
console.log(\'冰淇淋制作完成!!!\')
})
在代码层面,使用 Promise 之后,解决了多层回调函数调用导致的“金字塔”现象。让我们看看实现效果:
请转至 MDN 关于 Promise 的解释:Promise - JavaScript | MDN
以上是关于js怎样获取调用回调函数的参数值的主要内容,如果未能解决你的问题,请参考以下文章