简体   繁体   English

检测不提供回调的异步函数的执行结束

[英]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. 通常,异步函数async(arg, cb)例如async(arg, cb) )在末尾提供了回调函数占位符( cb ),因此您可以在异步例程结束时运行自己的代码。 What if the asynchronous function has no callback argument? 如果异步函数没有回调参数怎么办? Clearly with cb missing in: 显然cb在以下位置丢失:

async(args);
myFunction();

myFunction() will run first. myFunction()将首先运行。 How can I make myFunction() run only after async ends? 如何使myFunction()仅在async结束后运行? 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. 我的示例在Google Maps Directions服务中。 The asynchronous function is a drawing routine called directionsDisplay.setDirections(result); 异步函数是一个名为directionsDisplay.setDirections(result);的绘制例程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. 我将setTimeout为3秒,以便实现所需的操作,但这是一个笨拙的解决方案。 Altering the Google Maps API seems out of the question. 更改Google Maps API似乎是不可能的。 What could be better? 还有什么比这更好呢?

The directions service is here. 指示服务在这里。

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

Simply choose a city in either dropdown. 只需在任一下拉列表中选择一个城市。 After 3 seconds the map should move. 3秒后,地图应移动。

A simple Google search found me this related post: Google Maps V3 setDirections() callback 一个简单的Google搜索找到了以下相关帖子: Google Maps V3 setDirections()回调

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. Javascript是单线程的,不具有信号灯或互斥锁之类的同步功能。 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. 没有任何自尊的API提供者会为您提供异步功能的API,而没有某种能力知道它何时完成。 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). 如果确实如此,那将是一个非常糟糕的API,您必须进入该API的源实现,找到处理事件完成的位置并安装回调(通过修改原始源)。 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. 当然,更好的解决方案-而不是让DirectionsRenderer更新地图,然后jsut自己再次更改地图-是要让DirectionsRenderer首先不要更新地图。

Then you are free to recenter it as you wish. 然后,您可以随意更新它。

See https://developers.google.com/maps/documentation/javascript/reference#DirectionsRendererOptions 请参阅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/ 像这样: 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 来源: Google Maps V3 setDirections()回调

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. 您可以尝试弄清楚代码是如何异步进行的,也许是setTimeout(func,1)调用。 You could then override the setTimeout function and fetch the call, adding a callback to it possibly. 然后,您可以覆盖setTimeout函数并获取调用,并可能向其添加回调。 But that's a pretty unclean solution. 但这是一个非常不干净的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM