简体   繁体   中英

jQuery - pass array of functions to ajax success callback

I'm fairly new with jQuery, and I'm trying to call two functions on successful ajax (since the documentation says as of 1.5 success callback can take an array of functions).

If I do this, everything works fine:

$.ajax({
    url : sJSONFilePath,
    dataType : 'json',
    success : foo(data)
});

What do I need to do to pass in an array of functions? If I try the following, I get a "Uncaught TypeError: Cannot read property 'length' of undefined" error in the console:

$.ajax({
    url : sJSONFilePath,
    dataType : 'json',
    success : [foo(data), bar(data)]
});

I was unable to find any examples of this feature being used. Thanks in advance, and sorry if this is dumb.

There's no need for an array, you can use the deferred syntax that was also introduced in jQuery 1.5:

$.ajax(...).done(foo).done(bar);

This is generally cleaner and much more extensible than passing callback functions as parameters to $.ajax and relatives.

From the $.ajax() documentation :

The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information). For convenience and consistency with the callback names used by $.ajax() , jqXHR also provides .error() , .success() , and .complete() methods. These methods take a function argument that is called when the $.ajax() request terminates, and the function receives the same arguments as the correspondingly-named $.ajax() callback . This allows you to assign multiple callbacks on a single request , and even to assign callbacks after the request may have completed . (If the request is already complete, the callback is fired immediately.)

[but see the paragraph after, where it explains how .success , .error and .complete are now deprecated and replaced with .done , .fail and .always ]

What you do is this:

$.ajax({
    url : sJSONFilePath,
    dataType : 'json',
    success : function(data) {
        foo(data);
        bar(data);
    }
});

or this:

$.ajax({
    url : sJSONFilePath,
    dataType : 'json',
    success : [foo, bar]
});

Note that in the second one, I'm not calling foo and bar , I'm listing the function references in an array (since as you say, as of 1.5 jQuery's ajax callback options allow that).


You've said that this works fine:

$.ajax({
    url : sJSONFilePath,
    dataType : 'json',
    success : foo(data)
});

but it doesn't. What that does is immediately call the foo function, and then assign the return value of that function to the success property of the options you're passing to ajax . Unless you're using foo to build and return a function to use as the callback, that's not what you want to do.

It's important to understand the difference between calling a function and using a reference to it. If you have parens after the function name (with or without arguments in them), you're calling it. If you just have the name, you're referring to it. Eg:

var f = foo(); // CALLs `foo` and assigns return value to `f`
var f = foo;   // Assigns a reference to `foo` to `f`

when writing

success : [foo(data), bar(data)]

you are in fact evaluating the foo and bar functions (probably with a null argument)

you need to write

success : [foo, bar]

Why don't you call one function that calls the other two:

$.ajax({
    url : sJSONFilePath,
    dataType : 'json',
    success : foo_bar(data)
});

function foo_bar(data)
{
   foo(data);
   bar(data);
{

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM