This is the forty-second article of Jerry in 2021, and the 319th official account of the Wang Zixi public number.
When Jerry was engaged in the development of SAP commerce cloud foreground angular, he always kept in mind the sap ui5 development technology he had learned. I deliberately asked myself to compare SAP ui5 and angular in all aspects. I just hope I can have a certain technical accumulation in these two front-end development frameworks.
Recently, I encountered a problem in the foreground development of SAP e-commerce cloud, involving the usage of combinelate operator, so I have this article.
Search according to the keyword combinelatest in the sap e-commerce cloud source code and get 170 search results. This shows that it is widely used in SAP e-commerce cloud foreground development.
What business scenario is the combinelate operator applied to? The answer is in the field of reactive programming.
Jerry’s previous article,Jerry’s share at the 2020 SAP Global Technology Conference: text version of SAP Spartacus technology introduction, it has been mentioned that the new generation of SAP commerce cloud is based on the front-end interface of the open source project Spartacus project and supports responsiveness(Responsive) Layout and adaptation(Adaptive) Properties of the layout. Plus the response of this paper(Reactive) Programming, these three adjectives, when I first came into contact, I found it easy to confuse.
- Responsive design: through various front-end technologies, responsive design gives page elements the ability to automatically adjust the display behavior according to the change of screen resolution to achieve the best display effect.
- Adaptive design: implements different pages for different types of devices, and calls corresponding web pages after detecting the device resolution.
- Reactive programming: reactive programming is the name of a programming style. It is a sharp tool for us to solve the programming problems in asynchronous and concurrent fields. Reactive programming usually includes event driven, push mechanism, observer publisher mode and other characteristics. It essentially works on asynchronous data flow. The event response system constructed by responsive programming has a high degree of scalability, which will be shown by examples later in this paper.
In order to reduce the complexity of the example and make it easy for everyone to understand, Jerry abstracts the problems encountered in SAP commerce cloud into a simple model, which is implemented by using the traditional event processing method of SAP ui5 and the responsive programming library of angular rxjs, from which you can feel the difference.
First, the model is implemented with SAP ui5. Draw a red and a black button, and click it to add one to their respective counters. At the same time, there is a third counter, total. No matter which button is clicked, the total counter is also incremented by one.
The status in the figure below shows that the red button is clicked 5 times and the black button is clicked 2 times.
I bound a JSON model to the view controller, which contains three attributes: red, black and total, which are bound to the three counters of the XML view respectively. When the two buttons are clicked, the press event is triggered, and the corresponding processing function onpress is called to update the value of the corresponding counter in the function.
The implementation source code of this SAP ui5 application can be obtained at this link.
Then learn how to use the idea of responsive programming to solve this problem.
The angular application in the second half of this paper adopts the responsive programming mode to realize the same requirements. Rxjs is selected as the programming tool library, a well-known tool library in the field of responsive programming. At the same time, it is also famous for its steep learning curve.
Jerry once recorded a simple video to introduce the runtime effects of the two applications developed using SAP ui5 and angular rxjs:
The source code of the angular application mentioned in this article can be downloaded here.
The following figure is the view of angular application. This is a native HTML view, which defines the counters implemented by two buttons and three div tags.
For responsive programming based on rxjs, the core logic is shown in the figure below with 27 ~ 39 lines of code, a total of 12 lines of code. Although the number of lines is small, the amount of information is huge.
Observable (observable object) is the core concept of rxjs responsive programming pattern. It is the encapsulation and abstraction of asynchronous event flow by rxjs.
Compare the following figure, the traditional button event subscription mechanism implemented by addeventlistener and the comparison of two implementation methods based on rxjs observable.
Some friends may not understand that it seems useless to introduce the additional abstraction layer of observable object.
Let’s go back to the example of angular in this article.
The fromEvent operator receives two parameters, the data source of the event (such as the DOM element of the page control, which is returned through document. Getelementbyid), and the event name Click
The fromEvent operator returns an observable object that encapsulates the asynchronous event source. This asynchronous event source will release the mouseevent event object containing mouse click Details (called emit in rxjs) as the user clicks. The observable object returned by fromEvent releases the behavior of mouseevent object over time, which is described in the first horizontal line in the figure below.
The M legend in the horizontal line represents the mouseevent object instance. The coordinates on the horizontal line where the M legend is located represent the time stamp of mouse click on the button.
The pipe method of observable object supports the introduction of various operators, such as the pipe (mapto1 (1)) shown by the second horizontal line in the figure above. The semantics of this operation is to map the mouseevent object released when the user clicks the button into a constant 1. The mouseevent object contains the details of the user’s click event, such as the timestamp of the click, The X and Y coordinates of the mouse when clicking, and so on. However, our requirement is only to count the number of clicks, so we can use mapto (1) to map the mouseevent object to 1 for counting. Then use the scan operator, which receives an accumulation function as the input value and can maintain the accumulation value internally to meet the counting requirements.
Observable, operator, event objects released by observable, and processing functions subscribed to observable can be compared to parts to be processed on pipeline conveyor belt in reality for ease of understanding.
- The CNC machine tool in the lower left corner of the figure above is equivalent to an observable object. The energy source continuously releases the parts to be processed, that is, the event object.
- Parts on the pipeline: equivalent to event objects released by observable objects. The parts will pass through several Manipulators on the assembly line in turn and be processed by the latter. The shape of the parts processed by the manipulator changes, such as mouseevent in this example. After mapto (1) processing, the deformation is constant 1
- Manipulator: many operators in rxjs
- The operator of the assembly line terminal: label the final processed parts, such as the subscriber of the observable object (the consumer of the event object).
Look back at the combinelatest operator in the angular example in this article. It can combine any number of original observable objects (the red input parameter in the figure below) and return a new observable object (the blue output parameter in the figure below). I call it a joint asynchronous event object. In this example, the observable object corresponding to the red button and the black button click event is processed by combinelatest, and the returned joint asynchronous event object is subscribed by the anonymous arrow function on line 28 below. The input parameter values passed into the anonymous object is an array containing two elements. The values are the total hits of the current red and black buttons. These total clicks are the values generated after processing based on the mouseevent generated by button clicking through the mapto and scan operator passed in the observable pipe method described above. The sum of the two elements in the values array is the total number of clicks of the current button. Therefore, in lines 28 to 30, the code assigns the elements in the values array to the innerHTML attribute of the red, black and total counters in turn to complete the interface rendering.
The joint asynchronous event object shown in the green dotted box in the following figure represents the mouseevent released by the object and the process processed by operators after the user clicks the red button four times and the black button three times. The purple horizontal line and blue legend at the bottom of the figure below represent the calculation logic of the total counter value after any user clicks the button: that is, the sum of the total clicks of the current two buttons.
As mentioned earlier in this paper, the asynchronous event model of responsive programming based on rxjs has high scalability. Suppose our demand for button click counting goes further: within a second, no matter how many times the customer clicks the button, it is only counted once.
Obviously, this is a typical functional anti shake scenario. Jerry’s previous articles introduced the implementation principles of function debounce and function throttle of SAP ui5 and angular, and once shared how SAP ui5 implements function anti shake.
Using angular rxjs, you can achieve this requirement more gracefully: insert an anti shake operator debouncetime in the pipe method. The anti shake interval is 1000 ms. the semantics is that no matter how many times the user clicks the button quickly in one second, the observable object will only send one mouseevent object to the subsequent operator of debouncetime, mapto (1)
The idea of realizing function anti shake in SAP ui5 is similar, but the application developer needs to write the anti shake function himself:
Finally, in this specific example of counting the number of button clicks, what advantages does responsive programming embody from the perspective of programming.
The button is the producer and the data source of the generated mouseevent. The user’s click action triggers the generation of mouseevent. The button click event handling function is equivalent to the consumer of mouseevent. In the consumer code implemented by SAP ui5, in addition to writing the logic to refresh the latest value of the counter to the UI, it is also responsible for maintaining the cumulative value of the counter. This is just like the workers at the end of the assembly line in reality. They are not only responsible for labeling the parts, but also responsible for processing the parts. To some extent, this practice violates the single responsibility and the separation of concerns principle
Ideally, like angular rxjs, the middle layer of observable and operators is introduced, so that the three roles perform their respective duties and responsibilities are clear:
- The button is responsible for generating the event object
- Observable and operators are responsible for processing event objects
- The subscriber of the event object directly consumes the processed event object
Understanding this series of responsive programming concepts introduced in this article is the basis for understanding these dazzling rxjs operators chain calls in SAP e-commerce cloud source code.
The man smiled and said, “a person’s martial arts have been divided into different factions and have fallen behind. If you follow me, I’ll give you a new ear and eye to teach you that martial arts has a unique world.”
Jerry used SAP ui5 for front-end development before. After contacting angular last year, he also felt that “front-end development has a unique world”.
Let’s take a test. Which expert in Jin Yong’s novel is the above paragraph in red italics? Thanks for reading.
More Jerry’s original articles are: “Wang Zixi”: