回調函數 : 函數作為參數傳遞到另外一個函數中。簡單數據類型和引入數據類型中的數組和對象作為參數傳遞大家肯定都不陌生,其實引用數據類型中的函數也是可以的。 事實上大家見到的很多,用到的也很多,比如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)