-1

I've a small example to get data from the ajax response (directly).

class foo {
    get baz() {
        return this.bar();
    }
    test(func) {
        this.bar = function () {
            return 'baz';
        };

        let res = func().done(this.bar);

        return this;
    }
}

let func = function () {
    return $.ajax({ url: '/', type: 'GET' });
};

let f = new foo();

// try to make a request with ajax
let result = f.test(func);

// then, show the response
// no need to use callback function here
console.log(result.baz);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

So, my question: is using callback inside ajax obsolete?

Everything I need to do: make a request, then, wait for the request completes and show the response.

This syntax is out:

let onSuccess = function () {};
let onError = function () {};

$.ajax({}).done(onSuccess).fail(onError);

UPDATE:

This code would return the target response:

get baz() {
    return this.bar ? this.bar() : undefined;
}

this.bar = function (res) {
    return res;
};
  • 1
    Your "This syntax is out" is using the same features as your example that you seem to be saying is "in". Can you clarify the question, please? – T.J. Crowder Aug 12 '17 at 08:44
  • @T.J.Crowder Okay. If I make it as an js framework, that would be helpful (I think). So, I can tell to the users that: don't use the callbacks, you can use `this syntax` instead. Do you agree with me? –  Aug 12 '17 at 08:47
  • I still don't understand the question. You're going to use callbacks no matter what, whatever style you use; the function you pass `then` is a callback. I have no idea where `this` comes into your question at all. – T.J. Crowder Aug 12 '17 at 08:48
  • *"This code would return the target response"* No, it wouldn't. I recommend actually creating a real working example with ajax calls. Once you have it working in your own environment, you'll realize that you need callbacks or polling, as I described in my answer. If you want to share your results in the question, Stack Snippets don't support ajax but you can put all the code in the question with a link to jsFiddle, which does support ajax. (At some point you might be tempted to use `async: false`. Don't, it hangs up the browser while the call is outstanding.) – T.J. Crowder Aug 12 '17 at 09:29

1 Answers1

2

If what you're saying is that you think you've created a structure where, literally, the caller doesn't have to use a callback at all, you're mistaken.

This code is incorrect:

// try to make a request with ajax
let result = f.test(func);

// then, show the response
// no need to use callback function here
console.log(result.baz);

result.baz will not have a meaningful value until the ajax call has completed. That's the whole point of callbacks: They let you know when a meaningful value is available. See How do I return the response from an asynchronous call?

So is this code in the class:

get baz() {
    return this.bar();
}

and in test:

this.bar = function () {
    return 'baz';
};

That will always return "baz", because this.bar is hardcoded to return "baz".

Fundamentally, to get the result of an asynchronous operation, you have to have a callback or polling mechanism. With the new async/await syntax in ES2017, you can seem to avoid using callbacks:

async function getTheStuff() {
    const data = await $.ajax({/*...*/});
    // ...
    return data;
}

...but there are still callbacks being used behind the scenes.

There are other problems with the code (test acts a bit like a constructor or builder, but it isn't one; multiple calls to test will overwrite the bar function, meaning you can't access the first result), but that's the main one: It fails to handle the asynchronous nature of ajax calls.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • `result.baz will not have a meaningful value until the ajax call has completed` That's exactly what I mean. What's `incorrect`? There is no reason to get the value before running the request. –  Aug 12 '17 at 09:02
  • @Alan: Incorrect as in it won't work. The code *starts* the request, but then tries to read the result before the result has been returned by the asynchronous process. Again, please read the linked question's answers. – T.J. Crowder Aug 12 '17 at 09:04
  • Maybe I misunderstood about some concepts. But It's still working. You can try to click `Run code snippet` to test. I'm reading the related question. Thanks! –  Aug 12 '17 at 09:08
  • @Alan: As I said above: It will always return `"baz"`, because it's hardcoded. But that has nothing whatsoever to do with ajax. You could remove all the ajax parts and it would still return `"baz"`. Try making it work with an actual ajax call, and you'll soon see the problem (which is described in detail in the linked question's answers). – T.J. Crowder Aug 12 '17 at 09:10
  • I just update the question based on your complaining. –  Aug 12 '17 at 09:15
  • @Alan: I'm not complaining. I'm trying to *help you* by making you understand why your code won't work as expected, and help you understand the need for callbacks. If you don't want help, posting on SO is a strange way to show it. – T.J. Crowder Aug 12 '17 at 09:18
  • Sorry. I'm not angry. It's just a small example and can be improved for future since I don't like to use `callback`. I don't agree with you at all for some cases. Thanks for help! –  Aug 12 '17 at 09:41
  • @Alan: You're welcome. If you "don't agree" that you need callbacks or polling to deal with getting an asynchronous result, with all due respect, it's not a matter of opinion; it's a matter of fact, easily proven. – T.J. Crowder Aug 12 '17 at 09:48
  • Im going to create a new `fact`. –  Aug 12 '17 at 10:13
  • @Alan: Yeah. Let me know how that works out for you. – T.J. Crowder Aug 12 '17 at 10:16