简体   繁体   中英

Detecting the end of execution of an asynchronous function that provides no callback

Normally an asynchronous function, let's say async(arg, cb) , provides a callback function placeholder ( cb ) at the end so you can run your own code when the asynchronous routine ends. What if the asynchronous function has no callback argument? Clearly with cb missing in:

async(args);
myFunction();

myFunction() will run first. How can I make myFunction() run only after async ends? I tried writing my own callback wrappers without success; they were merely redirecting the function calls.

EDIT I'm interested in an answer to the above but I will give an example of how I ran into this situation.

My example is in the Google Maps Directions service. The asynchronous function is a drawing routine called directionsDisplay.setDirections(result); , and I want to recenter and zoom in after the drawing completes. I put together a setTimeout of 3 seconds so that what I want happens, but it's a clumsy solution. Altering the Google Maps API seems out of the question. What could be better?

The directions service is here.

http://jsfiddle.net/ryxtj/1/

Simply choose a city in either dropdown. After 3 seconds the map should move.

A simple Google search found me this related post: Google Maps V3 setDirections() callback

Which shows adding an event listener for when the directions change.

Javascript is single threaded and does NOT have synchronization capabilities like semaphores or mutexes. Thus, there is no ability to make your code "wait" until an async function completes or turn an async function into a synchronous one.

The only way to solve this is with event handlers and/or callback functions. No self respecting provider of APIs will give you an API to an asynchronous function without some ability to know when it completes. If they do, it's a really crummy API and you'd have to go into the source implementation for that API, find where the completion of the event is handled and install a callback (by modifying the original source). Unless they've already provided for completion events or completion callbacks in the design, there's nothing else you can do from "outside" the code.

Surely a better solution - rather than letting DirectionsRenderer recenter the map, and then jsut change it again yourself - is to tell DirectionsRenderer to NOT recenter the map in the first place.

Then you are free to recenter it as you wish.

See https://developers.google.com/maps/documentation/javascript/reference#DirectionsRendererOptions

can tell it to preserveViewport - then you dont need to bother with any messy listeners.

Like this: http://jsfiddle.net/8kbf2/1/

This should provide you with the callback/event:

google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
  // ... CALLBACK
});

Source: Google Maps V3 setDirections() callback

On the other part of your question: No, you cant synchronize an asynchronous call directly without any modification to the code that is causing it or some hacky overrides.

For Example:
You could try to figure out how the code is beeing asynchronized, maybe it's a setTimeout(func,1) call. You could then override the setTimeout function and fetch the call, adding a callback to it possibly. But that's a pretty unclean solution.

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