3

I have been trying to wrap my head around jquery deferred and then functions. As I gather from jQuery then documentation, the then function sends the return value of the callback to the next then handler if they are so chained. Given that, why is my code not working as expected?

function log(message) {
  var d = new Date();
  $('#output').append('<div>' + d.getSeconds() + '.' + d.getMilliseconds() + ': ' + message + '</div>');
}

function asyncWait(millis) {
  var dfd = $.Deferred();
  setTimeout(function () {
    var d = new Date();
    log('done waiting for ' + millis + 'ms');
    dfd.resolve(millis);
  }, millis);

  return dfd.promise();
}

function startTest0() {
  return asyncWait(1000).then(asyncWait).then(asyncWait).then(asyncWait).done(function () {
    log('all done, 4 times');
  });
}

function startTest() {
  asyncWait(500).then(function () {
    return asyncwait(1000);
  }).then(function () {
    return asyncWait(1500);
  }).then(function () {
    return asyncWait(2000);
  }).done(function () {
    log('all done');
  });
}

log('welcome');
log('starting test ...');
startTest0().done(function() { log('starting the second test'); startTest(); });

JS Fiddle here: Sample code. I was expecting a similar behavior in both tests but something eludes me. What am I missing?

Thanks in advance!

EDIT: See an updated DEMO where I am trying to chain the async operations to start after the previous one is done.

1
  • 1
    "I am trying to chain the async operations to start after the previous one is done." - That is precisely what your code would do, if you had actually fixed the typo that I mentioned in my answer. Commented Oct 16, 2015 at 5:13

2 Answers 2

3

Except for one typo (asyncwait instead of asyncWait) your code works. Check below.

function log(message) {
  var d = new Date();
  $('#output').append('<div>' + d.getSeconds() + '.' + d.getMilliseconds() + ': ' + message + '</div>');
}

function asyncWait(millis) {
  var dfd = $.Deferred();
  setTimeout(function () {
    var d = new Date();
    log('done waiting for ' + millis + 'ms');
    dfd.resolve(millis);
  }, millis);

  return dfd.promise();
}

function startTest0() {
  return asyncWait(1000).then(asyncWait).then(asyncWait).then(asyncWait).done(function () {
    log('all done, 4 times');
  });
}

function startTest() {
  asyncWait(500).then(function () {
    return asyncWait(1000);
  }).then(function () {
    return asyncWait(1500);
  }).then(function () {
    return asyncWait(2000);
  }).done(function () {
    log('all done');
  });
}

log('welcome');
log('starting test ...');
startTest0().done(function() { log('starting the second test'); startTest(); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="output"></div>

Lesson to learn: Put any JS code through jshint before and after you fix bugs.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes. Short of lint, the clue to this was the console error.
That was the other lesson I wanted to mention. ;)
Thanks so much! I had put this through JSHint on JSFiddle, but it didn't catch any errors. :-(. I didn't check console. Thanks for reminding.
0

As i can see here, you are calling startTest0 function returning its promise object and calling then callback without returning new times into next then callback. I modified your startTest() into this :

function startTest() {
  return asyncWait(500).then(function () {
    asyncWait(1000);
    return 1500; // here we pass to the next then
  }).then(function (ms) { // ms here we got 1500       
    asyncWait(ms);
    return 2000; // here we pass to the next then
  }).then(function (ms) { // ms here we got 2000       
    asyncWait(ms)
    return asyncWait(2500);
  }).done(function () {
    log('all done');
  });
}

DEMO

1 Comment

In your example all the async operations start at pretty much the same time, right? Can you see my updated demo - jsfiddle.net/cdasari/awux3k9d? I tried to chain the async operations to start only after the previous one was completed. Just like in the startTest0 example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.