原文網址:http://blog.yam.com/tagtoo/article/30242304
以下原文轉載
------------------------------------------------------------------------------------------------------------
最近試著把Tagtoo的服務中 利用到facebook api的部分改成新版的api
由於當初第一次寫的時候有step by step的tutorial 而那篇tutorial裡面講到的功能 差不多就是我要的
所以不費太多心思就把它完成了 現在新版api似乎還找不到那麼詳細的教學
便花了一些時間摸索 這裡是一些心得 備忘之餘 若能幫其他開發者省一點時間
也是功德一件摟~
Note: 我用的純粹是 javascript SDK
先來講一個很容易發生的錯誤
以上的code做的事很簡單-- 取得用facebook connect登入你網站的網友之email
我們將會以facebook api進行查詢(第5~10行) 然後用變數"email"來存這個查詢到的值
注意第4 9 和 11行都是單純的alert指令 目的只是方便觀察變數email的值
不算是實質內容的一部分
實際執行上述程式碼 會發現一個很奇怪的現象
總共出現三次對話視窗 內容分別是
1st: outside: undefined(第4行的執行結果)
2nd: outside: undefinde(第11行的執行結果)
3rd: zouber@gmail.com(第9行的執行結果)
若是沒經驗的話 一定會覺得很奇怪
我明明在第7行已經賦與email值了 怎麼還是undefined?
仔細一想 合理的解釋 應該是第11行優先於第7行執行了
按理說程式運行原則上是由上至下逐行執行才對 怎麼會這樣?
可以先動動腦...
動動腦時間
問題出在第5行 當我們用facebook api查詢網友資料時
其實就隱含了ajax的意涵在裏頭 我們實際上是對facebook的server發了一個ajax request
也因為如此 所以這類的facebook api都少不了指定一個callback function
亦即當這個請求完成時 原頁面必須要有對應的後續處理
所以 看起來輕輕鬆鬆的一行程式碼 其實已經隱含了複雜的ajax request發出程序在裏頭
相信對ajax稍有概念的人就知道 ajax其實就是為了達成媲美桌面應用程式的反應性產生的技術
達成的方式是當使用者發出此類的請求後 用非同步的方式去處理它
簡單來說就是發出請求後 原網頁繼續運行 完全不會有任何停滯
同時請求傳到伺服器 同步處理 直到處理完畢 用戶端收到通知
啟動callback function 處理伺服器回傳的資料(也可能沒有任何回傳資料)
一個有點類似的概念是飛彈的"射後不理"
戰機射出飛彈後 完全不必理它 此時戰機和飛彈各做各的事
像兩個不相干的個體 一段時間後戰機會收到通知以了解飛彈的去向
最終戰機會收到通知 便可知道飛彈到底是擊中目標還是失誤
所以本來是一直線的程式執行流程
到了第5行以後分岔成兩支
一支是程式原本的流程A
另一支是新啟動的 對facebook資料庫進行查詢的流程B兩個流程同步進行 流程B進行完畢後 才會執行第6~9行
而流程A直接就執行接下來的第11行
所以 第7行和第11行之間變成沒有絕對的順序關係
而以現階段的網路速度來說 有非常大的機率是第11行比第7行(必須等遠端請求完成)還要先被執行
也就是我們所看到的實驗結果
這個bug道理其實不難 只是簡短一兩行facebook api就能進行ajax機制時
我們必須時時注意 別被下意識的直覺騙了
debug很累的...
Note: 若對本範例涉及的api有興趣 請見此頁 和 此頁
要取得網友的email 必須在他登入facebook connect 時請求權限
FBML語法: "<fb:login-button perms='email, publish_stream'></fb:login-button>"
其中perms屬性即列舉所有想請求的權限 就本例而言
我請求了取得網友email以及發布訊息到他塗鴉牆(publish_stream)的權限
zouber
留言列表