This is the simplified version of my problem:
var callback_one = function (result_from_web_service) {
console.log('callback one');
};
var callback_two = function (result_from_web_service) {
console.log('callback two');
};
// the async_calls are library calls that i don't own or modify
var x = function () {
console.log('x is called');
async_call_one(callback_one);
async_call_two(callback_two);
};
var y = function () {
console.log('y is called');
};
Test:
x();
y();
// prints: 'x is called', 'y is called', 'callback one', 'callback two'
// what i need: 'x is called', 'callback one', 'callback two', 'y is called'
What I did to accomplish this was calling y() inside call_back_two:
var callback_two = function (result_from_web_service) {
console.log('callback two');
y();
};
But now my use case requires that y be called outside of the callback (will be called by the user of my code). i.e. the calling of x() and y() be independent in a way that the calling of x() doesn't end up calling y(). y() should be called independently but only if x() and its callbacks are processed. think of x() as like creating an object in java and y() as a method you would call whenever you want.
//.. some code, x() does some kind of initialization...
x();
// OPTIONALLY call y(), but make sure x() and its callbacks are processed
y();
I tried the below but doesn't work.
$.when(x()).then(y());
Thanks,
The only way to make something like this work properly is to make
y
asynchronous. Basically,y
internally waits forx
to complete before executing its own code. This is similar to things likedomready
oronload
which waits for other things to happen before executing their own logic.There are two ways to accomplish this. The first, simplest and most naive way is
setTimeout
polling. Makex
set a variable or attribute and check that before executing:The second method is to create virtual events or promises. Not all promise libraries support using a promise that has already expired (my own homemade one does) so you may need to write your own control flow to handle that case. For this you need to rewrite
x
to support an event or promise-like api:Now in
y
you can use thex.loaded
function to execute your code when x is loaded:Of course, this has the problem of making
y
asynchronous. Therefore if your users expect to write something like:then
a
andb
may or may not execute beforey
. To solve this you need to makey
accept a callback so that you users can control their program flow:or:
So they'd have to use
y
like this:Alternatively you can make
y
return a promise if you prefer that style.A little bit down the road to spaghetti code but you could wrap up the two callbacks together by setting variables they both can see and only call y() when they both return.
for example
However if you have to use jquery promises, you need to return a promise object to use $.when,
and inside the asyncs you need to do
though that would only work for one of your async calls so you would need another $.when inside the first function, so it can get sloppy quick.