回调函数 : 函数作为参数传递到另外一个函数中。简单数据类型和引入数据类型中的数组和对象作为参数传递大家肯定都不陌生,其实引用数据类型中的函数也是可以的。
事实上大家见到的很多,用到的也很多,比如jQuery中的一些事件,定时器。这些呢都是别人搞好的,大家直接用,所以就没有太在意。
/注意到click方法中是一个函数而不是一个变量
//它就是回调函数
$("#btn_1").click(function() {
alert("Btn 1 Clicked");
});
它也是回调函数
setInterval(function(){
console.log('回调函数')
})
回调函数是如何运作的呢?
我们把一个函数传入,那么这个函数什么时候执行,执行的条件是什么?
这个是由被调用的函数决定的,被调用函数可以在一个适当的条件去触发这个回调函数,
比如上诉点击事件,什么时候触发这个函数呢?那就是点击的时候,其实jQuery封装的时候,也可以函数调用的时候立马执行,也可以把传入的函数放入定时器,间隔一段事件执行,
那么这些毫无意义嘛!!!总之就是传入的这个函数执行条件,时间,同步或异步都可以随意控制,很强大。
回调函数其实也是闭包:
如何理解这个呢? 当我们把这个函数当参数传递到其他函数时候,那么其实会形成闭包的。大家想想闭包的概念,内部函数应用外包函数变量。当然其实传入的函数也不一定非要应用外部函数的变量。
function fn(id, check) {
info = {
id: id
}
console.log(id)
check(info)
}
fn(1, function(data) {
console.log(data)
})
上面是我写的一个简单的回调函数,当然没有任何意义啊,只是写出来便于看的,
其实上溯回调函数中还涉及到一个回调函数传值问题,fn函数调用的时候传入一个函数,这个函数调用时候,其实有一个传值问题
1传到上诉fn函数中,fn函数中的info同时也传到了fn调用中的data。
回调函数不好的影响:回调地狱
var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory});
p_client.open(function(err, p_client) {
p_client.dropDatabase(function(err, done) {
p_client.createCollection('test_custom_key', function(err, collection) {
collection.insert({'a':1}, function(err, docs) {
collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) {
cursor.toArray(function(err, items) {
test.assertEquals(1, items.length);
// Let's close the db
p_client.close();
});
});
});
});
});
});
上溯是随便拷贝的回调函数代码,这个是不是特别难看,而且不利于代码维护,如何解决这个问题呢?es6提供了解决方案,promise解决回调函数问题。
接下类在聊聊promise的使用吧。推荐大家可以看一看阮一峰的一片文章,什么文章我也不知道,但是你百度搜索:阮一峰es6。
为什么会有promise? 之前大家解决异步事件都是用回调函数去解决,就是说,写异步事件用回调函数去写。但是回调函数写异步会出现一些问题,
回调地狱的问题,上诉代码大家可以看到的。那么promise就是一种新的处理异步的方法,可以完美的解决回调函数处理异步带来的问题,回调地狱问题。
其实promise就是异步操作的方法,就像之前的定时器一样,看到定时器就知道这是异步操作,同样,看到promise就知道这个是异步操作。
什么是promise?
promise是一个构造函数 首先要构建一个promise对象
const promise = new Promise() 那马儿promise对象就建立好了
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
new promise 传入的参数一个是函数,函数中还有两个参数,这两个是函数,就是回调函数,什么时候执行呢?成功会执行resolved函数,失败执行reject函数,
成功时候可以传入参数,失败的时候也可以传入参数,value和error就是传入的参数,这两个参数可以通过promise .then和.catch方法绑定的函数中去获取,
成功的时候同时会调用.then方法并且把成功的参数传入到.then方法绑定的函数中去。.catch同理会这样。
、下面简单写了一个demon
var i = 1
function promise() {
const promise = new Promise(function(resolved, reject) {
if (i === 1) {
resolved(i)
} else {
reject(1)
}
})
return promise
}
console.log(23)
promise().then(function(value) {
console.log(value)
}).catch(function(value) {
console.log(value)
})
console.log(32)