ArcGIS API for JavaScript 4.2 Learning notes [7] Eagle eye (thumbnail implementation and asynchronous processing, Promise, callback function, listening notes)

Source: Internet
Author: User
Tags first string

Before the text: About style is the CSS of the page is not a comment, because the official example of the style is too simple, copy read.

This article has a lot of AJS 4.x version added content, such as listening watch, promise object, callback function, asynchronous processing and other content, the original rational things I will explain at the end of the text, you crossing don't worry about not understand, I try to explain these in popular language.

Convention, if you are not accustomed to see the tail from the beginning, you can jump directly to the back to see summary .

You should have seen the thumbnail function of the business map, right? Take the Niang map for example, when using the Street View map, the lower left corner will appear a location of the same 2D small map:

This is the application of Eagle Eye function, in many desktop software such as Erdas, Envi, Eagle Eye is very common.

If the following hyperlinks update later than 4.3 or later, look for 4.2 of the sample mates to learn from this article ~

This is the example of 2D overview map in Sceneview.

Source code: Point Me

In fact, a 2D mapview in 3D sceneview display, the key is in the synchronization of data, the official point of Watch () method is the key.

Talk not much, first on the final:

Structure is probably, Big Div put sceneview, small div put mapview.

The small Div also has a black area to identify the area of the current Sceneview. The widgets of the small div is removed.

The HTML code is:

<Body>  <DivID= "Viewdiv"></Div>  <DivID= "Overviewdiv">    <DivID= "Extentdiv"></Div>  </Div></Body>

As usual, require gives a reference (formerly called the first string array parameter, in order to save trouble, called directly after the reference)

require (    [      "Esri/map",      "Esri/views/sceneview",      "Esri/views/mapview" ,      " Esri/core/watchutils ",      " Dojo/dom ",      " Dojo/promise/all "      ," dojo/ domready! "     ],     function (Map, Sceneview, Mapview, Watchutils, Dom, all) {        // your code     });

The focus should be:

View's Watch () method, watchutils when method, view's Toscreen method, view's Extent property, view's then method.

Since there are two view (DIV), then there must be two copies of the map (data).

So the second parameter (the previous article called the function parameter, then the second parameter) defines the map and view as follows:

 var  mainmap = new   Map ({basemap: " hybrid "" World-elevation "});  var  overviewmap = new   Map ({basemap: " OSM "});  var  mainView = new   Sceneview ({container: " Viewdiv " var  mapview = new   Mapview ({container: " Overviewdiv "

Mainmap, Mainview is 3D, Overviewmap, Mapview is 2D.

Of course, we see the small map of 2D is not zoomed out of those controls, just 1 lines of code, you can empty those controls.

      MapView.ui.components = [];

The Lookup API lets you know that the UI property is the Defaultui class and Defaultui inherits from the UI class. Components are arrays of strings, and empty if the assignment is null. Accordingly, the Defaultui class has the remove and empty methods to clear the control, not to elaborate.

For ease of operation, take the DOM element of the current region's Div "Extenddiv" as a variable:

var extentdiv = Dom.byid ("Extentdiv");

Complete the preparation section above.

Next, after the data is loaded, the 2D map and 3D map will be "synchronized", using the two view then method.

The then () method is a unique method of promise objects, and what promise is for the moment is no need to know, as long as the promise in AJS 4.x is a very important thing.

Also, the Mapview and Sceneview classes inherit the Promise class. In addition, many of the methods in AJS 4.x return are promise objects.

Let's look at the then method of Mainview (3D view) and see what it does:

Mainview.then (function() {  Mainview.goto ({    Center: [7,],    200000,     and,      
{ true, 100000 })});

Well, it takes a parameter, and the type is the method. What did this anonymous method do? This is not the last article in the scale animation! (GoTo) Skip, look at the then method of Mapview (2D view) to see what it does:

Mapview.then (function() { ("Extent", updateoverviewextent); ("Extent", updateoverviewextent); Watchutils.when (MainView,"Stationary", Updateoverview); functionUpdateoverview () {Mapview.goto ({, Scale:mainView.scale* 2 * MATH.MAX (Mainview.width/Mapview.width, Mainview.height/mapview.height)}); }  functionupdateoverviewextent () {varextent =mainview.extent; varBottomleft =Mapview.toscreen (Extent.xmin, extent.ymin); varTopRight =Mapview.toscreen (Extent.xmax, Extent.ymax); Topright.y + "px"; Bottomleft.x + "px"; (BOTTOMLEFT.Y-TOPRIGHT.Y) + "px"; (topright.x-bottomleft.x) + "px"; }});
the then method of Mapview

It's a long way.

I'll explain it slowly.

Still accept a method as a parameter (why then is the parameter so strange?) will be explained at the end of the article)

Digression: In JavaScript, the function/method is very common, the function/method is a variable type JS, in C + + can pass the function pointer, in C # can pass the delegate variable.

There are two methods in this method, named Updateoverview and Updateoverviewextent, and we take the code of this then method apart from the two methods, and find that watch and Watchutils.when are paired with these two methods.


//Two views are bound to the Updateoverviewextent ("Extent", updateoverviewextent); ("Extent", updateoverviewextent);functionupdateoverviewextent () {varextent =mainview.extent; varBottomleft =Mapview.toscreen (Extent.xmin, extent.ymin); varTopRight =Mapview.toscreen (Extent.xmax, Extent.ymax); Topright.y + "px"; Bottomleft.x + "px"; (BOTTOMLEFT.Y-TOPRIGHT.Y) + "px"; (topright.x-bottomleft.x) + "px";}

Consult the API, knowing that the view's parent class accessor supports the watch method. It is worth mentioning that in order to realize the monitoring changes, the ajs4.x version specifically provides the Watch method instead of the previous old method.

The usage of Watch is:

object. Watch ("The property name that needs to be monitored", the callback function that needs to be executed after the property changes);

When an object listens to one of its properties, the property will execute some code once it has changed.

In this case, the extent (range) attribute of the two view object needs to be monitored, and once the extent is changed, the Updateoverviewextent () method is executed.

The approximate meaning of the updateoverviewextent () method is: Get the range of the 3D view, get the 2D view diagonal two corners and change the dimension properties of the DOM element for the area box above the 2D view (top, left, height, Width

The light changes the area box is not good, also must change the 2D map the scope.

Watchutils.when (MainView, "stationary", Updateoverview); function Updateoverview () {  Mapview.goto ({,    * 2 * MATH.MAX (Mainview.width/       Mapview.width,       / mapview.height)  });}

Watchutils This object is a class that is located under the Esri/core/watchutils module.

What it means is to listen to an object and execute the given method when one of the properties of the object is true.

The lookup API learns that this class provides when this static method, when the meaning of the method is:

So, in this case, the meaning is:

When mainview the "stationary" property of this 3D view object is true, the 2D view object is refreshed Mapview.

Refreshing a 2D View object The main use of the Goto () method mentioned in the previous article, this example only specifies an object anonymous object that consists of both the center and scale properties.

The stationary property of the Sceneview class is Boolean, meaning whether the current view is already stationary (the general view is animated by the mouse Drag or goto () method, and once stopped, the stationary becomes true)

Sum up.

This example is probably the idea:

• Instantiate two map and two view first, and then use the then () method to zoom to the specified location after the creation of the 3D Mainview.

• Where 2D Mapview is created, the then () method is used to listen for the extent property of the two view, and also to listen for the stationary property of the 3D view.

• When the extent attribute changes, the range box above the 2D view changes first, and then the 2D map changes immediately.

• Refresh the 2D view when the 3D view is still down.

Listening is relatively good understanding, need to pay attention to not much, notice that watch and Watchutils.when both methods return is the Watchhandle object. After the study after more monitoring, and then carefully look at other monitoring methods.

The difficulty lies in the then method.


Then () How did the method come? This starts with the new specification Promise object for ES6 (full name ECMAScript 2015). ECMAScript is the standard of JavaScript, JS is the implementation of ES.

What is promise? This thing says complex is also very complex, it is:

To handle the tedious and difficult-to-read maintenance of multi-layered callback functions for asynchronous operations, a new canonical class initiated by the COMMONJS community.

The most notable feature is that the objects it instantiates have the then () and catch () methods (promisea+ specification?). It seems to be)

In AJS, classes that inherit the promise are:

All the Layers

Mapview, Sceneview, Layerview


There are countless classes that can return promise objects.

So why use promise?

This again starts with the asynchronous Operation .


In AJS 4.x, data (map classes) and Views (view classes) are separate, and 3.x version drawing rendering is done by map itself.

Because the view view class is separated, the drawing logic becomes its main function. Of course, the drawing will not be very fast, there are often a process, especially the large amount of data in the drawing of the time there will be a relatively long waiting process.

Therefore, in JS, the longer processing will be thrown to asynchronous processing (that is, several operations at the same time)

But, we know that JS is single-threaded, how does it handle asynchronous processing? Simply put, JS asynchronous processing is actually a "pseudo-async", is to complete the synchronous code before executing asynchronous code.

Typically, asynchronous code does a lot of computational work, while synchronous code does some less time-consuming initialization. So

The synchronization code spends a small amount of time initializing something, in which n asynchronous tasks are dropped to the asynchronous queue. When the synchronization code finishes initializing (the time is short), the asynchronous code begins to execute sequentially.

For example: the construction of the interface to the synchronization code, while there are N background data exchange, processing, calculation of the task, will be thrown to the asynchronous queue to prepare. When the interface is constructed (often very short, almost seconds), the asynchronous code is executed at a later time.

This first look at the interface will make the experience much better, if the asynchronous code (which is the time-consuming task) in the synchronization code execution, then due to the nature of synchronization, must wait for these time-consuming task execution to continue to go down (JS features, single-threaded)

"In this case"

Initializing view, I don't know how it works in the cloud (because I'm using a CDN to run the AJS program), but I know that the instantiation of the view is definitely an asynchronous operation.

That is, the loading of the Web page (3D earth and 2D map, synchronous), then the rendering of the view (mountain exaggeration, etc., asynchronous).

Sometimes, the asynchronous operation will of course have a result, such as asynchronous to take a long time to work out a matrix, but the synchronization code is over, the asynchronous task dropped the results have not come out, how to get it?

We can use a method to get it. This method, called the callback function in ancient times.

In the absence of the promise class, it is normal to use the callback function to implement (and also to use events, listen) asynchronously.

But when the callback function itself is an asynchronous operation, it becomes disoriented.

Asynchronous first layer, with the result to return the callback function to the synchronization code, the callback function is the second layer, the callback function needs to use a level two callback function to return the results to the first layer of->

As an example:

I am the leader, I have two things now: Have a thing to do, and tea.

These two things do not conflict, although this thing is boring, time-consuming (such as text input).

So I threw this thing to the manager (async first layer), I continued to drink tea (sync)

Async The first layer is the manager to do this thing, but this thing is mostly boring, the final collation is relatively simple.

So the manager throws the boring part to the clerk (the second level asynchronously) and waits for the clerk to finish the part and to have tea (in sync).

So, the result of the staff is a level two callback function, the staff to complete the results, "callback" to the manager.

The manager took the clerk's result and put it together, "callback" to the leader. (Second level asynchronous completion)

At this point the leader tea is finished (synchronized), and the task is completed (the first layer is completed asynchronously).

If you use the old way of writing will be very annoying, if using promise then writing is

The leader has to do something. Then (function () {Let the manager do})

. then (function () {Let the Employee do});

Chain style, simple, easy to see, but also easy to maintain.

Then the function inside is the callback function that tells the asynchronous task how to handle a piece of code for the asynchronous result when it is finished.

Finally, look at the syntax of the then method:

Then (function resolve, function rejected);

We usually only use the previous parameter, that is, how to handle the asynchronous success. The next parameter is what to do when the asynchronous task fails to process.

Even the AJS official gave the third parameter of what to do in the process ... That's not all that much.


Presumably after this process, we know that the view object is a Promise object (inheritance), and there is a process of asynchronous operation.

So, Mainview.then (function () {...}); The meaning is

When the 3D view is successful on a server-side asynchronous operation, use Goto () to zoom to the specified location.

At the end of the article, I would also like to say that listening, monitoring in the AJS 3.x version is done through the event, and AJS 4.x new use of the Watch faction notation. For these you can refer to the Guide documentation for AJS 4.2.

Finally, on the async and callback function Part I also learned a day after the vague definition, I hope you can read it ... I'm not quite able to understand that the state-given multilayer then () is this:

Source: Point Me

Then, of course, it's a method, no argument. Only when the result of the child layer is complete, the parent layer then can complete the asynchronous with the callback of the result of the child layer.

Give me some of the things I read that explain the Async, callback functions:

Plain English explanation promise

ECMAScript 6 Getting Started

4 ways to program JavaScript asynchronously

Baidu knows how to understand the callback function in-js

The asynchronous principle of JavaScript asynchronous programming

The callback function in JS, and the callback in ES6 through promise

ArcGIS API for JavaScript 4.2 Learning notes [7] Eagle eye (thumbnail implementation and asynchronous processing, Promise, callback function, listening notes)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.