上一篇我们在讨论 AJAX 的时候,有另外提到 Callback Function,不知道怎麽的我突然想花更多的时间去研究这个 function,所以这一篇就用更多的 Callback Function 范例把它塞满好了 (?)
Callback Function,也称做「回呼函式」,在前面的例子中我们可以大概看到, Callback Function只会在满足某项条件以後被动的去执行,简单来说就是「在一个函式执行完後,会依照条件去执行传递进来的函式」。
直接进入范例:
var isFirst = function (callback) {
console.log('is first!');
callback(); // 执行传入的 isSecond()
}
// callback function
var isSecond = function () {
console.log('is second!')
}
isFirst(isSecond);
isFirst
函式执行完以後才会执行 isSecond
函式,并且 isSecond
会被代入到 callback,isSecond
即为一个 Callback Function。
结果:
is first!
is second!
但这样其实看起来跟平常的函式没有什麽太大的不同,平常的函式不也是长这个样子吗?
var isFirst = function (callback) {
console.log('is first!');
}
var isSecond = function () {
console.log('is second!')
}
isFirst();
isSecond();
结果:
is first!
is second!
我们可以来试试比较明显的例子,以下面这个例子来说,isFirst
中加入了 setTimeout
,setTimeout
为非同步的处理方法,同步与非同步在前面文章有提到,它的第一个参数为时间到时要被执行的程序,第二个参数为延迟的时间 ( 豪秒 )。
var isFirst = function () {
setTimeout(function() {
console.log('is first!')
}, 2000); // 非同步,2秒後才执行
}
var isSecond = function () {
console.log('is second!')
}
isFirst();
isSecond();
结果:
is second!
// 2秒後
is first!
从结果来看 isFirst
函式被设定延迟,加上 setTimeout
是非同步方法,因此不会等到 isFirst
回传结果,而是先继续执行 isSecond
函式,那麽如果我们希望 isSecond
函式可以在印出 is first! 之後才执行呢?这时候就必须使用 Callback Function 来处理。
var isFirst = function (callback) {
setTimeout(function() {
console.log('is first!')
callback();
}, 2000); // 非同步,2秒後才执行
}
// callback function
var isSecond = function () {
console.log('is second!')
}
isFirst(isSecond);
结果:
// 2秒後
is first!
is second!
可以看到,使用 Callback Function 之後,is second! 可以确保在 is first! 印出後才出现,符合 Callback Function 会在满足一个条件以後才会再次执行另一个程序的原则。
另外再塞一个看起来比较复杂一点点的 Callback Function 范例:
//定义函式
function prepare(ingredients, callback) {
console.log("Preparing" + ingredients);
callback();
}
//调用函式
prepare("onions and garlic", function chop() {
console.log("Chopping" );
});
prepare()
代入了两个参数,第一个为 ingredients
,然後使用 chop()
的 Callback Function 作为第二个参数,此时 chop()
会代入 callback()
,力求简洁的写法把 chop()
直接代入到 prepare()
中,结果为:
Preparing onions and garlic
Chopping
呈上面的例子, Callback Function 也可以是匿名函式:
//定义函式
function prepare(ingredients, callback) {
console.log("Preparing" + ingredients);
callback();
}
//调用函式
prepare("onions and garlic", () => {
console.log("Chopping" );
});
现在我们的 Callback Function 是匿名的,它不叫做「chop」了。
结果:
Preparing onions and garlic
Chopping
Callback Function 是作为另一个主函式传递参数的函式, Callback Function 在主函式内部执行,并且由主函式决定何时执行它。
现在已经知道执行 Callback Function 的主函式有权决定何时执行,而且不只这样,主函式能替Callback Function 决定的东西很多,它也可以将参数传递给 Callback Function。底下为带参数的Callback Function 例子:
//定义函式
function prepare(ingredients, callback) {
console.log("Preparing " + ingredients);
// 这边替 Callback Function 加上了参数
callback(ingredients);
}
//调用函式
prepare("onions and garlic", function chop(arg) {
// chop() 代入 arg 参数
console.log("Chopping " + arg);
});
这边我们不只是调用 chop()
这支 Callback Function,我们将它变成参数传入,并且告诉它在执行的时候回传 "Chopping " 以及参数。
结果:
Preparing onions and garlic
Chopping onions and garlic
虽然我觉得写到这里应该差不多了(X),但是 Callback Function 的好处比我原本想像的还更多,因此我只好继续写下去。不过好加在这是最後一个例子了,脑袋得以回氧再做冲刺,哈哈。
Callback Function 也是函式,这意思是说它也可以做任何函式能做的事情,这边有一个例子,假设我们希望回传底下这个结果:
Preparing onions and garlic
Chopping onions
为了呈现这样的结果,表示 Callback Function 必须过滤掉不要用的词。
function chop(ingredients){
var value = ingredients.match(/\bonions\b/g);
if (value){
console.log("Chopping " + value);
} else {
console.log("Not chopping");
}
}
在这个范例中,它必须确认 “ onions ” 这个词有没有在参数中,如果有就回传 “ Chopping onions ”,如果没有则回传 " Not chopping "。
function prepare(ingredients, callback) {
console.log("Preparing " + ingredients);
callback(ingredients);
}
function chop(ingredients){
var value = ingredients.match(/\bonions\b/g);
if (value){
console.log("Chopping " + value);
} else {
console.log("Not chopping");
}
}
prepare("onions and garlic", chop);
最後这个例子可能复杂了一点,主要是它除了调用 Callback Function 之外,还另外使用了 match()
方法来查找字串是否有匹配,不过如果对 match()
方法是有理解的,这最後一个范例应该也还是不难懂,不妨在看这一范例的时候,先去了解一下 match()
方法,比较不会觉得恐慌 (?)
参考资料:
JavaScript 什麽是Callback函式 (Callback Function)?
>>: android studio 30天学习笔记 -day 22-Dagger 前言
大家好,我是毛毛。ヾ(´∀ ˋ)ノ 废话不多说开始今天的解题Day~ 13. Roman to In...
程序码: import pandas as pd head5=pd.util.testing.mak...
一路走来 不知不觉已到了Day30了,这一天说长不长说短不短。 其实大概从Day5开始,就已经觉得很...
人类沟通需要技巧,程序语言靠的是方法。 我们除了可以透过 Props 来让父元件传值给子元件外,也...
本篇音乐分享 本篇文章会提到的 上一篇衍生题:include,与extend差异? missing-...