开发者

JavaScript/jQuery - "Array" of Arguments - Possible?

Doing some client-side JavaScript development, which requires me to call a client-side API which only accepts one parameter at a time (cough, cough, facebook).

Ba开发者_JAVA百科sically i need to call an API method twice:

someFBApi.requestPerms('email')
someFBApi.requestPerms('publish_stream')

Now, i have a wrapper function for this call which looks like this:

function requestPermission(permission, callback) {
 someFBApi.requestPerms(permission, callback);
}

But the problem is, i have to call the function "requestPermission" twice from all over the place:

requestPermission('email', function(perm1granted) {
   requestPermission('publish_stream', function(perm2granted) {
      // do something with perm 1 and perm 2

I would like to be able to do this:

requestPermissions('email,publish_stream', function(firstPerm,secondPerm) {
   // do something with firstPerm, secondPerm

I know i have to call FB API twice (fine), but i want that 'doubling up' to occur in that function (not all over the place). Know what i mean?

So, i'll accept an answer of two forms:

  • Can i pass an array of strings, iterate through those? (maybe JSON?)
  • Delimeted-string, then split the string in the function.

Keep in mind the function returns a value indicating whether or not the permission was granted. So it needs to accept an array/delimited list of strings and return an array/delimited list of strings.

The more simple the solution, the better. (jQuery fine)


Don't be tempted to use the string parsing solution. An array is cleaner and simpler:

/* note: permisions is expected to be an array */
function requestPermission(permissions) {
    for (var i=0; i<permissions.length; i++) {
        doSomething(permissions[i]);
    }
}

Now, the only problem would seem to be what to do with the callback. I'm assuming that the API is asynchronous and you'd want something like this:

doSomething(when_done)->doSomething...(finally)->execute_callback

For that you can use a sort of recursion. Except it wouldn't really be recursion in the traditional sense since each call happen asynchronously. Something like:

/* note: permisions is expected to be an array */
function requestPermission(permissions,callback) {
    var p = permissions.shift();
    var f = callback;
    if (permissions.length > 0) {
        // if this is not the last permission then
        // call this function again in the callback:
        f = function () {
            requestPermission(permissions,callback);
        }
    }
    someFBApi.requestPerms(p,f);
}

Now you can use it like this:

requestPermissions(['email','publish_stream'],finalCallback);


Using some array juggling you can drain items from a permissions array while accruing results in a results array. Tricky use of requestPerms's callback parameter will have our function be called once for each permission request to be performed, culminating in a call to the user's callback function once all of the permission requests have been performed.

function requestPermissions(permissions, callback, results) {
    if (typeof(results) == "undefined") {
        results = [];
    }

    // Call requestPerms with the first element in permissions and have
    // it add the result to the results array and then call requestPermissions()
    // again recursively to handle the next request.    
    if (permissions.length > 0) {
        var permission = permissions.shift();

        someFBApi.requestPerms(permission, function(result) {
            results.add(result);
            requestPermissions(permissions, callback, results);
        }
    }
    // We've handled all of the permission requests, so now--finally--call the
    // user's callback function.
    else {
        callback.call(results);
    }
}

# Usage
requestPermissions(
    ['email', 'publish_stream'],
    function(emailPerm, publishPerm) {
        // Do something with emailPerm and publishPerm.
    }
);

This is completely untested, but hey, that's what you get for free!


.

function requestPermissions(permissions, callback, ret) {
    // ret is a map of the success of the permissions
    if (!ret) ret = {};

    // Request the first permission in the array.
    FB.requestPerms(permissions[0], function (r) {
        ret[permissions[0]] = r;

        // If it was successful and there are more permissions 
        // to ask for, call requestPermissions again.
        // (If it wasn't successful, don't continue.)
        if (r && permissions[1])
            requestPermissions(permissions.slice(1), callback, ret);

        // Otherwise, call the callback.
        else
            callback(ret);
    });
}

requestPermissions(['email', 'publish_stream'], function (success) {
    if (success['email'] && success['publish_stream'])
        // ...
});

The above solution works sequentially, that is, one after another. I'm not sure how the Facebook API works, but if it allows requesting multiple permissions simultaneously, this could work too:

function requestPermissions(permissions, callback) {
    var ret = {};
    var count = permissions.length;

    // jQuery to make things easier
    $.each(permissions, function (i, value) {
        FB.requestPerms(permissions, function (success) {
            ret[value] = success;

            if (--count == 0) // Last one?
                callback(ret);
        });
    });
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜