在RequireJS中使用Require Within define

时间:2012-12-06 18:09:57

标签: javascript dojo requirejs js-amd

是否可以在define块中使用require?

我正在尝试加载facebook JS API,但需要将其包含在具有不同上下文的require中,因为如果Facebook被防火墙阻止,我不希望整个应用程序停止加载。

我遇到的问题是如何从嵌套的require()调用中返回模块。

我的代码看起来像这样:

define( [ 'require' ], 
    function( require ) 
{
    var fbRequire = require( 
    { 
        context: 'fb',
        waitSeconds: 3
    } );

    fbRequire.onError = function()
    {
        console.warn( 'fbRequire.onError', arguments );
    };

    fbRequire( [ 'https://connect.facebook.net/en_US/all/debug.js' ], 
        function() 
    {
        console.log( 'facebook file now loaded' );

        // init the Facebook JS SDK
        var facebookSettings = {
            channelUrl: '//' + window.location.hostname + '/facebook-channel.html', // Channel File for x-domain communication
            status: true, 
            cookie: true, 
            xfbml: true,
            appId: '1234567890'
        };

        FB.init( facebookSettings );

        // this is the bit I'm confused about
        // how do I...
        return FB;
        // ...because it's asynchronous and needs to be returned from the define() call?
    } );
} );

这是一个Dojo项目,如果有帮助(我是否需要使用dojo / Deferred?)。

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题但是在Facebook被阻止时无法让Dojo加载器失败。相反,我使用直接JS来加载SDK。希望这会帮助其他人。

define( [ 'require' ], 
    function( require ) 
    {
        return {
            /**
             * Loads a facebook asynchronously using require() and a "bang" (!).
             * 
             * @example require( ['my-project/facebookLoader!'],    function( facebook ) { ... } );
             */
            load: function( store, require, callback )
            {
                // already loaded?
                if( window.FB !== undefined )
                {
                    console.log( 'facebook already loaded - using global FB object.' );
                    callback( window.FB );
                }
                else
                {
                    require( [ 'dojo/dom-construct', 
                        'dojo/_base/window', 
                        'dojo/on',
                        'dojo/_base/event' ], // remove "/debug" in live env
                    function( domConstruct, win, on, event ) 
                    {
                        // add Facebook div
                        domConstruct.create( 'div', { id:'fb-root' }, win.body(), 'first' );

                        // init the Facebook JS SDK
                        var facebookSettings = {
                            channelUrl: '//' + window.location.hostname + '/facebook-channel.html', // Channel File for x-domain communication
                            status: false, // check the login status upon init?
                            cookie: true, // set sessions cookies to allow your server to access the session?
                            xfbml: false    // parse XFBML tags on this page?
                        };

                        // app ID from the App Dashboard
                        if( window.location.hostname == 'localhost' )
                        {
                            facebookSettings.appId = '123456788'; 
                        }
                        else
                        {
                            facebookSettings.appId = '123456789'; 
                        }

                        // what do we do if Facebook is blocked or times out?
                        var loadFailed = function( errorEvent )
                        {
                            console.warn( 'Facebook failed to load. Some features will be unavailable. ' + ( errorEvent ? 'Script error.' : 'Timed out.' ) );

                            // scrap the timer (in case we got here from error event on script tag)
                            if( timerId )
                            {
                                window.clearTimeout( timerId );
                            }

                            if( errorEvent !== undefined )
                            {
                                event.stop( errorEvent );
                            }

                            window.fbAsyncInit = function(){}; // noop

                            // return fake Facebook object
                            callback( 
                            { 
                                getLoginStatus: function()
                                {
                                    return false;
                                }
                            } );

                        };

                        // give Facebook 5 seconds to load
                        var timerId = window.setTimeout( loadFailed, 5000 );

                        // hook into Facebook's load callback
                        window.fbAsyncInit = function() 
                        {
                            window.clearTimeout( timerId );
                            FB.init( facebookSettings );
                            callback(  window.FB );
                        };

                        // Load the SDK Asynchronously
                        ( function(d)
                        {
                            var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
                            if (d.getElementById(id)) {return;}
                            js = d.createElement('script'); js.id = id; js.async = true;
                            js.src = "//connect.facebook.net/en_US/all/debug.js"; // dev version
                            //js.src = "//connect.facebook.net/en_US/all.js"; // production version
                            on( js, 'error', loadFailed );
                            ref.parentNode.insertBefore(js, ref);
                        }( document ) );

                    } );
                }
            }
        };
    } 
);