Javascript operation stream-callback

Source: Internet
Author: User

The operation flow is generated when the execution of a function depends on the results of multiple asynchronous operations. This is actually a type of event distribution. Use ie only as follows:

 
Document. attachevent ("onclick", function () {alert ("Fire click") ;}); var E = document. createeventobject (); document. fireevent ("onclick", e );

Jquery is written as follows:

 
$ (Document). Click (function () {alert ("Fire click") ;}). Trigger ("click ")

Jquery can also correspond to custom events, but the implementation of custom events in all libraries is similar. However, this type of event distribution can only be targeted at a specified event. Sometimes I wonder if these custom events need to exist.

For example, if a game needs to use QTE to create a boss, such as S + D + F, jquery is used to implement the following:

 var keys = 0, keystatetime = 0; function checkinterval () {If (! Keystatetime) {keystatetime = new date;} else {var now = new date-keystatetime; If (now> 500) {keystatetime = keys = 0 ;}}$ (document ). BIND ("keypress", function (e) {If (E. which = 115 | E. which = 100 | E. which = 102) {// SDF keys + = E. which; checkinterval (); // The interval between each operation of the hotkey should be small Dom. fire ("QTE") }}); $ (document ). BIND ("QTE", function (e) {If (Keys = 115 + 100 + 102 & keystatetime) {console. log ("Starting attack") }}); 

We cannot say that the QTE event depends on the keypress event. To be precise, the attack operation depends on three pressing operations that meet the conditions. Keypress binding is only a preliminary preparation. The real Association is between callback and callback. The QTE callback function is the callback of the preceding three callbacks. If the callback function of the event function is used as an operation. The four of them are oneOperation Flow. Hotkey is an identifier used to remove and distribute objects in this process.

Now, the topic is officially entered.

The process of using existing resources to process and transform existing things and things to generate the target results is called operation.

There are two types of operations: synchronous operations and asynchronous operations. Synchronization operations, such as setstyle, getattribute, El. innerhtml = "XXX", are synchronized. For asynchronous operations, see events and setTimeout callback.

Synchronization is real-time, congested, and will inevitably happen. Asynchronous operations are delayed, non-blocking, and unpredictable.

EventIt is a general term for step-by-step operations with the same features after classification. This category name is their event name, click, keypress, resize, scroll ....

The existing Event System does not set the corresponding API for this complex callback, but it is not surprising that many JavaScript frameworks are written by experts from other languages, their thinking is procedural or Oo, not functional. Asynchronous programming is not as prominent as Js in other languages. For example, the browser needs to process resource loading. Therefore, the top-down Synchronous Programming style must be replaced by the callback style. If one callback depends on the result of another callback, we will be stuck in the built-in callback.

Therefore, to solve this problem, we must have a mechanism to implementMulti-channel listeners,Collect the results of each callback in the process,Trigger final callback. Is this process very similar to the module loading system. The module loading process requests multiple dependent modules through the require method, and assembles the results of each requested module into the framework, execute the final callback when all dependencies exist in the box plus.

The following are some APIs for implementing the operation flow:

    • Use the VaR flow = Dom. Flow (names, FN, reload) Factory method to generate an operation stream. It doesn't matter if there are any parameters. It also calls the bind method on the prototype.
    • Flow. BIND (names, FN, reload) to implement multi-channel listening. names is a string separated by commas or spaces, and each word is the operation to be monitored,
      FN is the final callback. When the reload value is Boolean and false, for example, the last callback depends on the other four callbacks. Once these four Callbacks are successfully executed, the last callback is executed. Each time these four Callbacks are executed, the final callback will be executed immediately. If it is true, the final callback will be executed only after the four Callbacks are re-executed. If this parameter is left blank, the default value is false.
    • Flow. Fire (name, RET) is used to trigger the final callback. The name is a word in names and RET is optional. It will become one of the final callback parameters.
    • Flow. Unbind (names, FN), remove listener, FN (optional), remove all callbacks corresponding to names if no.

Well, let's review the above QTE implementation, and its implementation is not rigorous, because players may suddenly press asdfg. In addition, we also need to ensure the key order. The first time must be S, the second time is d, and the third time is F. Therefore, it is most appropriate to use the operation stream. The QTE Implementation of the game above is implemented using the mass framework as follows:

Dom. Require ("Ready, node, event, flow", function () {var keystatetime = 0, I = 0; function checkinterval () {If (! Keystatetime) {keystatetime = new date;} else {var now = new date-keystatetime; If (now> 500) {keystatetime = 0 ;}} var flow = Dom. flow ("0_115, 1_100, 2_102", function () {If (keystatetime) {I =-1; Dom. log ("Starting attack") }}, true); DOM (document ). BIND ("keypress", function (e) {checkinterval (); Dom. log (I + "_" + E. which) flow. fire (I + "_" + E. which); I ++ if (I = 3 | E. which = 13) {// press enter to retry I = 0 ;}});});

The operation stream has many advantages. I can say something that is probably said by another author similar to implementing eventproxy. What can we do to avoid callback nesting, turning serial wait into parallel wait, merging in one place, triggering in multiple places ...... Eventproxy solves the same problem as my operation flow. The difference is the implementation method. My operation flow is only a simplified version of my module loading system, the value of the state of the object corresponding to the dependency list is used to determine whether to execute the final callback, while the eventproxy is determined by times whether to execute the final callback.

 
VaR event = Dom. Flow (",", function () {// This is completely equal to assignall API for (VAR I = 0; I! = 4; ++ I) {console. log (arguments [I]) ;}}); console. log ("first"); event. fire ("1", 1); event. fire ("2", 2); event. fire ("3", 3); event. fire ("3", 3.5); event. fire ("4", 4); console. log ("second"); event. fire ("1", 1); event. fire ("2", 2); event. fire ("3", 3); event. fire ("4", 4);/** first123.54second123.00003.0000341234 */

<Br/> <! Doctype HTML> <br/> <HTML lang = "en"> <br/> <pead> <br/> <meta charset = "UTF-8"/> </P> <p> <title> operation stream by situ zhengmei </title> </P> <p> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8 "> <br/> <SCRIPT src =" http://files.cnblogs.com/rubylouvre/dom-combine.js "> </SCRIPT> </P> <p> <SCRIPT> <br/> Dom. require ("Ready, node, event, flow", function () {<br/> var keystatetime = 0, I = 0; <br/> function checkinterv Al () {<br/> If (! Keystatetime) {<br/> keystatetime = new date; <br/>}else {<br/> var now = new date-keystatetime; <br/> If (now> 1000) {<br/> keystatetime = 0; <br/>}< br/> var flow = Dom. flow ("0_115, 10000100, 2_102", function () {<br/> If (keystatetime) {<br/> I =-1; <br/> Dom. log ("START attack", true) <br/>}< br/>}, true); <br/> dom (document ). BIND ("keypress", function (e) {<br/> checkinterval (); <br/> Dom. l OG (I + "_" + E. which, true) <br/> flow. fire (I + "_" + E. which); <br/> I ++ <br/> if (I = 3 | E. which = 13) {// press enter to retry <br/> I = 0; <br/>}< br/> }); </P> <p> }); </P> <p> </SCRIPT> <br/> </pead> <br/> <body> <br/> <p> operation flow example </p> <br/> <p> Please quickly press SDF in turn! Press enter to restart (if no response is returned, refresh the page) </P> <p> </body> <br/> </ptml> <br/>

RunCode

The operation flow can probably cope with 90% of asynchronous operations, but it is still very weak in the face of transaction operations such as deposit withdrawal. I want to introduce the concept of "Lock. However, this will be a long time later, because the general ORM should help us solve this problem. The introduction is complete. Put the source code on GitHub and check it yourself.

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: info-contact@alibabacloud.com 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.