0

I'm trying to run 2 functions synchronously. The 1st function will execute a lot slower than the 2nd function. I need it to run synchronously from 1st to 2nd.

 //1st function
 function first(){
 $.getJSON("/update/", () => {
   //updates 
  })
 }

 //2nd function
 function second(){
  //triggers some event
 }

At this point, I've tried using Promise but to no avail, it was a fail

 //Promise

 var promiseVar = new Promise((resolve, reject) =>{
    first(); //run the first function
             //note: first() will take more time to run because it's
             //grabbing something from the server to update to client
    resolve('Success');
 })

 promiseVar.then((msg)=>{
    console.log(msg);
    second(); 
 })

By using Promise, it still executes the second function while loading the first. How can I make this run sequentially?

rgex
  • 119
  • 9
  • 1
    This general question has been asked hundreds of times here on stack overflow. – jfriend00 Oct 21 '17 at 00:54
  • @jfriend00 Would you estimate the question has been asked more than why `.then()` is undefined chained to a function call which does not return a `Promise`, or why value at chained `.then()` is undefined where no value is returned from previous `.then()`, or the former two inquiries have been asked the same amount of times as the current inquiry? – guest271314 Oct 21 '17 at 01:00
  • 2
    @guest271314 - I'm not counting. The point is the OP can do a little research and find lots of relevant answers. – jfriend00 Oct 21 '17 at 02:59
  • Other related answers: [How to synchronize a sequence of promises?](https://stackoverflow.com/questions/29880715/how-to-synchronize-a-sequence-of-promises/29906506#29906506), [Design pattern for managing multiple asynchronous JavaScript operations](https://stackoverflow.com/questions/6659489/design-pattern-for-managing-multiple-asynchronous-javascript-operations) and [Prefer way of doing multiple dependent ajax synchronous call](https://stackoverflow.com/questions/33200384/prefer-way-of-doing-multiple-dependent-ajax-synchronous-call/33200417#33200417) – jfriend00 Oct 21 '17 at 05:36
  • More related answers: [Run two functions with Ajax calls sequentially](https://stackoverflow.com/questions/33332491/run-two-functions-with-ajax-calls-sequentially/33332528#33332528) and [Sequential function calls in Javascript](https://stackoverflow.com/questions/23451163/sequential-function-calls-in-javascript/23453978#23453978). – jfriend00 Oct 21 '17 at 05:41

1 Answers1

0

return $.getJSON() call from first function, use .then(). Note jQuery.getJSON() returns a jQuery promise object which .then() can be chained to

function first() {
  return $.getJSON("/update/")
}

first()
.then(second, (jqxhr, textStatus, errorThrown) => console.error(errorThrown));

function first() {
  return $.Deferred(dfd => {
    setTimeout(() =>
      dfd.resolve("/update/"), Math.floor(Math.random() * 1500))
  }).promise()
}

function second(data) {
  console.log(data);
}

first()
  .then(second
  , (jqxhr, textStatus, errorThrown) => console.error(jqxhr, errorThrown))
  .fail(err => console.error(err)); // handle error for `second` call
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
guest271314
  • 1
  • 15
  • 104
  • 177
  • the only problem with this code is the unhandled rejection of `second` – Jaromanda X Oct 21 '17 at 00:38
  • @JaromandaX `(jqxhr, textStatus, errorThrown) => console.error(errorThrown)` handles jQuery promise returned from `first`. We do not have the code for `second` – guest271314 Oct 21 '17 at 00:39
  • I understand, just pointing out the flaw in the code – Jaromanda X Oct 21 '17 at 00:41
  • @JaromandaX What flaw is that? OP does not described `second` as being a `Promise` or jQuery promise object – guest271314 Oct 21 '17 at 00:42
  • 1
    you **added** rejection handling to `first` (not present in question), but you didn't do the same for `second` ... why pick and choose, do both or none :p – Jaromanda X Oct 21 '17 at 00:43
  • @JaromandaX See updated post – guest271314 Oct 21 '17 at 00:44
  • well, that works ... as long as `second` returns a jQuery Promise rather than a real Promise - I understand there's not enough information about what `second` does to correctly answer the question – Jaromanda X Oct 21 '17 at 00:49
  • @JaromandaX That is an indeterminate "as long as". jQuery promise implementation has several issues as to compatibility with Promises/A+ standard – guest271314 Oct 21 '17 at 00:53
  • indeed, if you read the dicumentation, you should be using `.done`, `.fail` and `.always` - no mention of `.then` or `.catch` at all - unless you dig down into the bowels of jquery documentation : – Jaromanda X Oct 21 '17 at 00:55
  • 1
    I would personally convert the Jquery promise into a real promise. As Jquery's is naff. For example edit your code to raise an exception in second. – Keith Oct 21 '17 at 00:55
  • @JaromandaX https://api.jquery.com/deferred.then. jQuery `deferred.done()` is different from jQuery `deferred.then()` – guest271314 Oct 21 '17 at 00:56
  • that's an absolutely absurd overreaction to a comment **I didn't even make** – Jaromanda X Oct 21 '17 at 01:04
  • That wasn't JaromandX, it was me.. jQuery has it's uses, but it's Promises are unfortunately flawed. Converting to a real Promise is pretty trivial. And yes, we could even omit jQuery altogether, things like `fetch` / `document.querySelectorAll` etc, are pretty standard now. – Keith Oct 21 '17 at 01:04
  • @JaromandaX Not an absurd "overreaction" at all, though you are correct, that comment should not have been attributed to you. – guest271314 Oct 21 '17 at 01:05
  • *Converting to a real Promise is pretty trivial* if all you want is `data` on success, and the full jqXHR object on rejection (from which you can get what you want, it's as simple as `Promise.resolve(jquery.naff)` – Jaromanda X Oct 21 '17 at 01:05
  • I didn't say it was an absurd comment, I said it was an absurd overreaction – Jaromanda X Oct 21 '17 at 01:06
  • @Keith Would try not to merge the two implementations. jQuery `.fail()` would not catch `Promise.reject()` returned from `second` – guest271314 Oct 21 '17 at 01:10
  • 1
    That's why I said convert jquery Promise to a real promise, and then `catch` works.. btw. If using ES6 a simple way to make second a Promise just use `async`.. After doing this, if you throw an Error in second, it's caught as expected. Like I said, if you throw an error in your second now, it's unhandled. – Keith Oct 21 '17 at 01:16