Sử dụng Facebook JavaScript SDK với async/await

Bài viết sau tạo một wrapper để sử dụng Facebook API theo phong cách JavaScript ES7 dùng async/await, giúp mã nguồn ứng dụng Facebook trở nên gọn gàng hơn.

Dưới đây là trái tim của chương trình 🙂 – class AsyncFB. Class này sẽ thay thế các API trong FB object của Facebook JavaScript SDK với phiên bản tương đương hỗ trợ Promise và async/await.

AsyncFB.js

'use strict';

class AsyncFB {
    // Singleton
    static getInstance() {
        if ( !AsyncFB.instance )
            AsyncFB.instance = new AsyncFB();
        return AsyncFB.instance.getScript();
    }

    // Load the Facebook JavaScript SDK
    getScript() {
        let inst = this;
        return new Promise((resolve) => {
            if (this.FB) {
                resolve(inst);
            } else {
                window.fbAsyncInit = function() {
                    Object.assign(inst, {
                        // Event Handling Methods
                        Event: window.FB.Event,
                        // App Events
                        AppEvents: window.FB.AppEvents,
                        // XFBML Methods
                        XFBML: window.FB.XFBML,
                        // Canvas Methods
                        Canvas: window.FB.Canvas,
                        // Facebook Object
                        FB: window.FB
                    });
                    resolve(inst);
                };
                (function(d, s, id) {
                    var js, fjs = d.getElementsByTagName(s)[0];
                    if (d.getElementById(id)) return;
                    js = d.createElement(s); js.id = id;
                    js.src = "https://connect.facebook.net/en_US/sdk.js";
                    fjs.parentNode.insertBefore(js, fjs);
                }(document, 'script', 'facebook-jssdk'));
            }
        });
    }

    // Initialize and setup the SDK
    init(params) {
        return new Promise((resolve) => {
            console.log('FB.init(', params, ')');
            this.FB.init(params);
            resolve(this);
        });
    }

    // Make an API call to the Graph API
    api(...params) {
        return new Promise((resolve) => {
            const callback = (response) => {
                console.log('FB.api(', params,') = ', response);
                resolve(response);
            };
            params.push(callback);
            this.FB.api(...params);
        });
    }

    // Trigger different forms of Facebook created UI dialogs,
    // such as the Feed dialog, or the Requests dialog.
    ui(params) {
        return new Promise((resolve) => {
            this.FB.ui(params, (response) => {
                console.log('FB.ui(', params,') = ', response);
                resolve(response);
            });
        });
    }

    // Returns the Facebook Login status of a user.
    getLoginStatus() {
        return new Promise((resolve) => {
            this.FB.getLoginStatus((response) => {
                console.log('FB.getLoginStatus() = ', response);
                resolve(response);
            });
        });
    }

    // Prompts a user to login to your app using the Login dialog in a popup. 
    login(params = { scope: 'public_profile,email' }) {
        return new Promise((resolve) => {
            this.FB.login((response) => {
                console.log('FB.login(', params,') = ', response);
                resolve(response);
            }, params);
        });
    }

    // Logout the current user both from your site or app and from Facebook.com.
    logout() {
        return new Promise((resolve) => {
            this.FB.logout((response) => {
                console.log('FB.logout() = ', response);
                resolve(response);
            });
        });
    }

    // Return the authResponse object without the overhead of an asynchronous call
    getAuthResponse() {
        console.log('FB.getAuthResponse()');
        return this.FB.getAuthResponse();
    }
}

Cách sử dụng

Đoạn mã sau demo cách sử dụng class AsyncFB và Facebook API với async / await. Hãy thay thế {app-id} bằng App ID của bạn và {api-version} bằng phiên bản Graph API đang sử dụng – hãy luôn sử dụng phiên bản mới nhất nhé.

<!DOCTYPE html>
<html>
<head>
<title>Facebook Login JavaScript Example</title>
<meta charset="UTF-8">
</head>
<body>
<div id="status"></div>
<script src="AsyncFB.js"></script>
<script>
(async function() {
    // Obtain the instance of async Facebook API
    let FB = await AsyncFB.getInstance();

    await FB.init({
        appId: '{app-id}',
        version: '{api-version}',
        cookie: true, // Enable cookies to allow the server to access the session.
        xfbml: false, // Parse social plugins on this webpage.
    });

    let authResponse = await FB.getLoginStatus();
    
    // Attempt to login
    if ('connected' !== authResponse.status)
        authResponse = await FB.login({ scope: 'public_profile,email' });

    if ('connected' !== authResponse.status) {
        document.getElementById('status').innerHTML =
            'Failed to log in!';
        return;
    }

    // Fetching your information using Graph API
    let response = await FB.api('/me');
    document.getElementById('status').innerHTML =
        'Thanks for logging in, ' + response.name + '!';
})();
</script>
</body>
</html>

Tham khảo