JavaScript promise using the detailed and asynchronous promise mode

Source: Internet
Author: User
Tags foreach error handling json

Promise Core Description

Although promise has its own specifications, but the current various types of promise libraries, in the promise implementation of the details are different, and some of the API even in the sense of a completely distinct. But the core content of promise is interlinked, it is the then method. In relevant terms, promise refers to an object or function that has a then method that triggers a particular behavior.

Promise can have different implementations, so the promise core description does not discuss any specific implementation code.

Read the Promise core description first means: Look, this is the result that needs to be written out, please refer to this result and think about how to write it in code.

Getting Started: Understanding promise in this way

Think back to what promise is solving? Callback. For example, the function DoMission1 () represents the first thing, now we want to do the next thing after this thing is done DoMission2 (), what should we do?

Let's take a look at our common callback patterns. DoMission1 () said: "If you want to do so, give DoMission2 () to me, I will help you call after the end." "So it would be:

DoMission1 (DoMission2);



What about the Promise model? You say to DoMission1 (): "No, control is in my place." You should change, you first return a special thing to me, then I will use this thing to arrange the next thing. "This particular thing is promise, and it will become this:

DoMission1 (). then (DoMission2);



Can be seen, promise will callback mode of the master-slave relationship replaced a position (turn to be the owner!) , the process relationships of multiple events can be focused on the main path (rather than being scattered within the individual event functions).

Well, how do you do such a transformation? In the simplest case, suppose the code for DoMission1 () is:

function DoMission1 (callback) {
var value = 1;  
callback (value);
}



Well, it can change, and it's like this:

function DoMission1 () {return
{
then:function (callback) {
var value = 1;  
callback (value);  
}  
};
}



This completes the conversion. While it's not actually a useful conversion, it has actually touched on the most important implementation point of promise, that is, promise converts the return value to an object with a then method.

Advanced: Design distance of Q

Starting from defer

Design/q0.js is the first step in the initial formation of Q. It creates a tool function called defer, which is used to create the promise:

var defer = function  ()  {     var pending = [],  value;     return {       resolve: function
  (_value)  {         value = _value;         for  (var i = 0, ii = pending.length;  i < ii; i++)  {           var  callback = pending[i];           callback ( Value);         }          pending = undefined;       },       then:  function  (callback)  {         if  (pending)  {      &NBsp;     pending.push (callback);         }
 else {           callback (value);         }       }     }   };



The source can see that running defer () will get an object that contains two methods of resolve and then. Think back to the deferred of jquery (which also has resolve and then), and these two methods will be similar. Then will refer to the state of the pending and, if it is a wait state, save the callback (push) or call the callback immediately. Resolve will be sure of this promise, updating the value while running all saved callbacks. Examples of the use of defer are as follows:

var oneonesecondlater = function () {
var result = defer ();  
settimeout (function () {
result.resolve (1);  
}, 1000);  return result
;
};



Oneonesecondlater (). then (callback);

Here Oneonesecondlater () contains asynchronous content (settimeout), but let it immediately return a defer () generated object and then place the object's resolve method at the end of the asynchronous call (with the value, or the result).

Here, there is a problem with the above code: Resolve can be executed multiple times. Therefore, resolve should be added to the state of the judgment, to ensure that resolve only once effective. This is the next design/q1.js of Q (Only the difference section):

resolve: function  (_value)  {     if   (pending)  {       value = _value;        for  (var i = 0, ii = pending.length; i < ii;  i++)  {         var callback = pending[i];          callback (value);       }        pending = undefined;     } else {        throw new error ("a promise can only be  Resolved once. ");      }  } 



for the second and more calls, you can throw an error like this, or you can ignore it directly.

Detach defer and Promise

in the previous implementation, defer generated objects both have then methods and resolve methods. By definition, promise is concerned with the then approach, and the resolve that triggers promise to change state is another matter. So, Q next will have the then method of promise, and have resolve defer separate, separate use. This is like a clear delineation of their respective responsibilities, leaving only a certain amount of authority, which will make the code logic clearer, easy to adjust. See Design/q3.js: (Q2 here skipped)

var&nbsp;ispromise&nbsp;=&nbsp;function&nbsp; (value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;return&nbsp;value&nbsp; &amp;&amp;&nbsp;typeof&nbsp;value.then&nbsp;===&nbsp; "function";&nbsp;&nbsp;};&nbsp;&nbsp; &nbsp;&nbsp; var &nbsp;defer&nbsp;=&nbsp;function&nbsp; () &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;var&nbsp;pending&nbsp;=&nbsp;[],&nbsp; value;&nbsp;&nbsp; &nbsp;&nbsp;return&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;resolve:&nbsp;function&nbsp; (_ Value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (pending) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;_value;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;for&nbsp; (var&nbsp;i&nbsp;=&nbsp;0,&nbsp;ii&nbsp;=&nbsp;pending.length;&nbsp;i&nbsp;&lt;&nbsp;ii; &nbsp;i++) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;callback &nbsp;=&nbsp;pending[i];&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;callback (value );&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pending&nbsp;=&nbsp;undefined;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;},&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;promise:&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then:&nbsp;function&nbsp; (callback) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (pending) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pending.push (callback) ;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;callback (value);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; &nbsp; &nbsp;&nbsp;};&nbsp;&nbsp;};



If you compare Q1 carefully, you will find that the difference is very small. On the one hand, the error is no longer thrown (instead of ignoring the second and more resolve), on the other hand, the then method is moved to an object named Promise. Here, run defer (called defer bar), will have the resolve method, and a promise attribute to point to another object. The other object is a promise that has only then methods. This completes the separation.

is preceded by a ispromise () function that determines whether an object is a promise (duck-typing method of judgment) by whether there is a then method. In order to properly use and process detached promise, it is necessary to distinguish promise from other values as such. The

implement promise Cascade

is a very important step. To the front to Q3, the implementation of the promise are not cascaded. But the promise you know should support this syntax:

Promise.then (STEP1). then (step2);  

The above process is understood to be that promise will be able to create new promise, and is taken from the old promise value (value in the preceding code). To implement then cascading, you need to do something: the

then method must return promise.

This returned promise must set its own value using the returned result of the callback passed to the then method. The callback that

passes to the then method must return a promise or value. In the

Design/q4.js, to do this, a new tool function ref:

var ref = function (value) {
if (value && typeof value.then = = "function") return
value;  Return
{
then:function (callback) {return
ref (callback (value));  
}  
};
};



This is the process of dealing with the value associated with the promise. This tool function will be packaged once for any value value and, if it is a promise, do nothing and, if not promise, wrap it into a promise. Note that there is a recursive, which ensures that the wrapped promise can be cascaded using the then method. To help understand it, here is an example of a use:

Ref ("Step1"). Then (function (value) {
console.log (value);//"Step1" return
15;
}). Then (function (value) {
console.log (value);



You can see how value is passed, and so does the promise cascade.

Design/q4.js converts the original defer into a cascading form by using this ref function in combination:

var&nbsp;defer&nbsp;=&nbsp;function&nbsp; () &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;var&nbsp;pending&nbsp;=&nbsp;[], &nbsp;value;&nbsp;&nbsp; &nbsp;&nbsp;return&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;resolve:&nbsp;function
&nbsp; (_value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (pending) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;ref (_value);&nbsp;//&nbsp;values&nbsp; wrapped&nbsp;in&nbsp;a&nbsp;promise&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp; (Var &nbsp;i&nbsp;=&nbsp;0,&nbsp;ii&nbsp;=&nbsp;pending.length;&nbsp;i&nbsp;&lt;&nbsp;ii;&nbsp;i++) &nbsp;{&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;callback&nbsp;=&nbsp;pending[i]; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value.then (callback);&nbsp;//&nbsp; then&nbsp;called&nbsp;instead&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pending&nbsp;=&nbsp;undefined;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;},&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;promise:&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;then:&nbsp;function&nbsp; (_callback) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;var&nbsp;result&nbsp;=&nbsp;defer ();&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; callback&nbsp;is&nbsp;wrapped&nbsp;so&nbsp;that&nbsp;its&nbsp;return&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//&nbsp;value&nbsp;is&nbsp;captured&nbsp;and&nbsp;used&nbsp;to&nbsp;resolve&nbsp;the&nbsp; promise&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;that&nbsp; "Then" &nbsp;returns&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;callback&nbsp;=&nbsp;function&nbsp; (value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.resolve (_callback (value) ); &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp; (Pending) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pending.push ( Callback);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value.then (callback);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp; result.promise;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; &nbsp; &nbsp;&nbsp;};&nbsp;&nbsp;};



The form of the original callback (value) is modified to Value.then (callback). The effect is actually the same as the original, just because value becomes the type of promise wrapper, it needs to be called. The

then method has more changes, it will first be reborn into a defer and return to the promise at the end of the defer. Note that callback is no longer the one that is passed directly to then, but adds a layer above it and places the newly generated defer resolve method here. As you can see here, the then method will return a newly generated promise, so you need to reserve the promise resolve, and the promise of the new resolve will run after the promise of the old resolve. This can be like a pipe, let the event according to the content of then connection, layer by layer pass down. The then method for

add error handling

Promise should contain two parameters, which are the processing functions for both positive and negative states (Onfulfilled and onrejected). The promise we have previously achieved can only be converted to a positive state, so the negative state section should be added next.

Note that the two parameters of the promise then method are optional parameters. Design/q6.js (Q5 also skipped) joined the tool function reject to help implement the negative state of promise:

var reject = function (reason) {return
{
then:function (callback, Errback) {return
ref (ER  Rback (reason));  
}  
};
};



The main difference between it and ref is that the then method of the object it returns will only run with the errback of the second argument. The remainder of the design/q6.js is:

var&nbsp;defer&nbsp;=&nbsp;function&nbsp; () &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;var&nbsp;pending&nbsp;=&nbsp;[], &nbsp;value;&nbsp;&nbsp; &nbsp;&nbsp;return&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;resolve:&nbsp;function
&nbsp; (_value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (pending) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;ref (_value);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp; (var&nbsp;i&nbsp;=&nbsp;0,&nbsp;ii&nbsp;=&nbsp;pending.length;&nbsp;i &nbsp;&lt;&nbsp;ii;&nbsp;i++) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Value.then.apply (Value,&nbsp;pending[i]);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pending&nbsp;=&nbsp;undefined;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;promise: &nbsp;{&nbsp;&nbsp; &NBsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then:&nbsp;function&nbsp; (_callback,&nbsp;_errback) &nbsp;{&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;defer ();&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;provide&nbsp;default&nbsp;callbacks&nbsp;and&nbsp;errbacks&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_callback&nbsp;=&nbsp;_callback&nbsp;| | &nbsp;function&nbsp; (value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// &nbsp;by&nbsp;default,&nbsp;forward&nbsp;fulfillment&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;return&nbsp;value;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_errback&nbsp;=&nbsp;_errback&nbsp;| | &nbsp;function&nbsp; (reason) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// &nbsp;by&nbsp;default,&nbsp;forward&nbsp;rejection&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;reject (reason);&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var &nbsp;callback&nbsp;=&nbsp;function&nbsp; (value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;result.resolve (_callback (value));&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;};&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;errback&nbsp;=&nbsp;function &nbsp; (reason) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.resolve (_ Errback (reason));&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (pending) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;pending.push ([Callback,&nbsp;errback]);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;}&nbsp;else&nbsP {&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value.then (Callback,&nbsp;errback); &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;return&nbsp;result.promise;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;};&nbsp;&nbsp;};



The main change here is to save the array pending in the form of a single callback instead of both positive and negative callbacks. Furthermore, the default positive and negative callbacks are defined in then, which makes the then method meet the requirements of the Promise 2 optional parameters.

You may notice that there is only one resolve method in defer, and there is no reject like jquery. So how does error handling trigger? Take a look at this example:

var defer1 = defer (),
promise1 = defer1.promise;  
Promise1.then (function (value) {
Console.log ("1:value =", value);   Return
reject ("error happens");
}).  Then (function (value) {
Console.log ("2:value =", value);
}).  Then (null, function (reason) {
Console.log ("3:reason =", reason);  
});  
Defer1.resolve (10); /
/Result:
//1:value = ten
//3:reason = error happens



As you can see, each return value passed to the then method is important, and it determines the result of the call to the next then method. If, as above, returning the object generated by the tool function reject, it triggers error handling.

Into the asynchronous

Finally to the end of the design/q7.js. Until the front of the Q6, there is a problem, is that the then method may be synchronized, or asynchronous, depending on the function passed to the then (for example, directly return a value, that is, synchronization, return a different promise, can be asynchronous). This uncertainty may pose a potential problem. So the next step in Q is to make sure that all then are converted to asynchronous.

Design/q7.js defines another tool function Enqueue:

var enqueue = function (callback) {
//process.nexttick (callback);//Nodejs
settimeout (callback, 1);//Na ? ve browser Solution
};



Obviously, this tool function defers any function to the next event queue.

Design/q7.js Other modification points are (show only the modifications):

var&nbsp;ref&nbsp;=&nbsp;function&nbsp; (value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;//&nbsp;...&nbsp;&nbsp; &nbsp;
&nbsp;return&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;then:&nbsp;function&nbsp; (callback) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;defer ();&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;//&nbsp;XXX&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enqueue (function&nbsp; () &nbsp;{&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.resolve (callback (value));&nbsp;&nbsp; &nbsp;&nbsp; &NBSP;&NBSP;&NBSP;&NBSP});&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;result.promise;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;};&nbsp;&nbsp;};&nbsp;&nbsp; &nbsp;&nbsp; var&nbsp;reject &nbsp;=&nbsp;function&nbsp; (reason) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;return&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;then:&nbsp;function&nbsp; (callback,&nbsp;errback) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Var&nBsp;result&nbsp;=&nbsp;defer ();&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;XXX&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enqueue (function&nbsp; () &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;result.resolve (errback (reason));&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;result.promise;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; &nbsp; &nbsp;&nbsp;};&nbsp;&nbsp;};&nbsp;&nbsp; &nbsp;&nbsp; var&nbsp;defer&nbsp;=&nbsp;function&nbsp; () &nbsp;{ &nbsp;&nbsp; &nbsp;&nbsp;var&nbsp;pending&nbsp;=&nbsp;[],&nbsp;value;&nbsp;&nbsp; &nbsp;&nbsp;return&nbsp;{ &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;resolve:&nbsp;function&nbsp; (_value) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//&nbsp;...&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enqueue ( function&nbsp; () &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Value.then.apply(Value,&nbsp;pending[i]);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp);&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;promise:&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then:&nbsp;function&nbsp; (_ Callback,&nbsp;_errback) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// &nbsp;...&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enqueue (function&nbsp; () &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value.then (callback , &nbsp;errback);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp);&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;&nbsp;};&nbsp;&nbsp;};










That is, the original value.then of the part, are converted to asynchronous.





To this, Q provides the promise design principle q0~q7, all end.





Conclusion





Even though this article has been so long, it is only the basic promise of the story. Most promise libraries will have more APIs to deal with more and promise-related requirements, such as all (), spread (), but, read here, you've learned the core idea of achieving promise, which will help you to apply promise in the future.





In my opinion, promise is a delicate design, and it took me quite some time to understand it almost. Q as a typical promise library, in the way of thinking is very clear. Can feel, again complex library is to start from the basic point first, if we want to do similar things, also should maintain this mentality 1.1 points progress.




















Promise mode of JavaScript asynchronous programming





Asynchronous mode is becoming more and more important in web programming, which is not very quick for web-mainstream JavaScript, so many JavaScript libraries (such as jquery and Dojo) add an abstraction called promise (sometimes called a deferred). These libraries allow developers to use the promise pattern in real-world programming. The official IE Blog recently published an article detailing how to use XMLHttpRequest2 to practice the promise model. Let's take a look at the relevant concepts and applications.





Consider an example where a Web page has an asynchronous operation (via XMLHttpRequest2 or WEB workers). With the deepening of Web 2.0 technology, the browser side has been subjected to more and more computational pressure, so "concurrency" has a positive significance. For developers, it is necessary to keep the interaction between the page and the user unaffected, and to coordinate the relationship between the page and the asynchronous task, and the programming requirements of this non-linear execution are difficult to adapt. Without the page interaction, we can think of two kinds of results--successful operations and failure handling--that need to be handled for asynchronous invocations. After a successful call, we may need to use the returned results in another AJAX request, which will result in a "function serial" case (explained in detail in the author's other article, "Nodejs's asynchronous Programming Style"). This situation can result in programming complexity. Look at the following code example (based on XMLHTTPREQUEST2):





Function&nbsp;searchtwitter (term,&nbsp;onload,&nbsp;onerror) &nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var
&nbsp;xhr,&nbsp;results,&nbsp;url; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;=&nbsp; ' http://search.twitter.com/search.json?rpp=100&amp;q= ' &nbsp;+
&nbsp;term;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xhr&nbsp;=&nbsp;new&nbsp;xmlhttprequest ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xhr.open (' Get ', &nbsp;url,&nbsp;true); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xhr.onload&nbsp;=&nbsp;function&nbsp; (e) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (this.status&nbsp;===&nbsp;200) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;results&nbsp;=&nbsp;json.parse (This.responseText);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onload (results);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xhr.onerror&nbsp;=&nbsp;function&nbsp; (e) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onerror (e);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xhr.send (); &NBSP} &nbsp; &nbsp;function&nbsp;handleerror (error) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;handle&nbsp; the&nbsp;error&nbsp;*/&nbsp;} &nbsp; &nbsp;function&nbsp;concatresults () &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* &nbsp;order&nbsp;tweets&nbsp;by&nbsp;date&nbsp;*/&nbsp;} &nbsp; &nbsp;function&nbsp;loadtweets () &nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;container&nbsp;=&nbsp;document.getelementbyid (' container '); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchtwitter (' #IE10 ',&nbsp;function&nbsp; (data1) &nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchtwitter (' #IE9 ',&nbsp;function&nbsp; (data2) &nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Reshuffle&nbsp;due&nbsp;to&nbsp;date&nbsp; * * &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;VAR&NBSP;TOTALRESULTS&NBsp;=&nbsp;concatresults (Data1.results,&nbsp;data2.results); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;totalresults.foreach (function &nbsp; (tweet) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;var&nbsp;el&nbsp;=&nbsp;document.createelement (' Li '); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
el.innertext&nbsp;=&nbsp;tweet.text; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Container.appendchild (EL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;},&NBSP;HANDLEERROR);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;},&NBSP;HANDLEERROR); &nbsp;}



The above code has the function of getting content from Twitter hashtag as IE10 and IE9 and displaying it on the page. This nested callback function is difficult to understand, and developers need to carefully analyze which code is used for the business logic of the application, and which code handles asynchronous function calls, and the code structure is fragmented. Error handling is also broken down, we need to detect the occurrence of errors in various places and make corresponding processing.

To reduce the complexity of asynchronous programming, developers have been looking for easy ways to handle asynchronous operations. One of the processing modes, called promise, represents a result that can run for a long time and does not necessarily have to be a complete operation. Instead of blocking and waiting for a long operation to complete, this pattern returns an object that represents the result of a commitment (promised).

Consider an example where the page code requires access to Third-party APIs, and network latency can result in longer response times, in which case asynchronous programming does not affect the entire page's interaction with the user. The promise pattern typically implements a method called then, which registers the corresponding callback function for state changes. For example, the following code example:

Searchtwitter (term). Then (Filterresults). then (DisplayResults);



The promise mode is in one of the following three states at any time: incomplete (unfulfilled), completed (resolved), and reject (rejected). Taking the Commonjs promise/a standard as an example, the then method on the Promise object is responsible for adding processing functions for the completed and rejected states. The then method returns another promise object to facilitate the formation of the promise pipeline, a way of returning promise objects that enables developers to concatenate asynchronous operations, such as then (Resolvedhandler, Rejectedhandler); The Resolvedhandler callback function fires when the Promise object enters the completion state and the result is passed, and the Rejectedhandler function is invoked in the rejected state.

With the promise model, we can implement the above example of Twitter again. To better understand the implementation approach, we try to build a framework of promise patterns from scratch. First you need some objects to store the promise.

var Promise = function () {/
* Initialize Promise */
};



Next, define the then method and accept two parameters to handle the completion and deny status.

Promise.prototype.then = function (onresolved, onrejected) {/
* Invoke handlers based upon state transition */
   };



At the same time, two methods are required to perform a state transition that has never been completed to completion and has never been completed until rejected.

Promise.prototype.resolve = function (value) {/* move from
unfulfilled to resolved */
};
Promise.prototype.reject = function (Error) {/* move from
unfulfilled to rejected *
/};



Now that we've built a promise shelf, we can go on to the example above, assuming that we're just getting IE10 content. Create a method to send an AJAX request and encapsulate it in the promise. This promise object specifies the process of completing and rejecting state transitions in xhr.onload and Xhr.onerror respectively, and note that the Searchtwitter function returns exactly the Promise object. Then, in Loadtweets, use the then method to set the callback function for the completion and deny state.

Function&nbsp;searchtwitter (term) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;url,&nbsp;xhr,&nbsp;results,&nbsp;
Promise &nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;=&nbsp; ' http://search.twitter.com/search.json?rpp=100&amp;q= ' &nbsp;+&nbsp;
Term
&nbsp;&nbsp;&nbsp;&nbsp;promise&nbsp;=&nbsp;new&nbsp;promise ();
&nbsp;&nbsp;&nbsp;&nbsp;xhr&nbsp;=&nbsp;new&nbsp;xmlhttprequest ();
&nbsp;&nbsp;&nbsp;&nbsp;xhr.open (' Get ', &nbsp;url,&nbsp;true); &nbsp;&nbsp;&nbsp;&nbsp;xhr.onload&nbsp;=&nbsp;function&nbsp; (e) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if&nbsp; (this.status&nbsp;===&nbsp;200) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;results&nbsp;=&nbsp;json.parse (This.responsetext);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;promise.resolve (results);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;xhr.onerror&nbsp;=&nbsp;function&nbsp; (e) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& nbSp;&nbsp;promise.reject (e);
&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;xhr.send ();
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;promise; } function&nbsp;loadtweets () &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;container&nbsp;=&nbsp;
document.getElementById (' container '); &nbsp;&nbsp;&nbsp;&nbsp;searchtwitter (' #IE10 '). Then (function&nbsp; (data) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;data.results.foreach function&nbsp; (tweet) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;el&nbsp;=&nbsp;document.createelement (' Li ');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.innerText&nbsp;=&nbsp;tweet.text;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.appendchild (EL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});
&NBSP;&NBSP;&NBSP;&NBSP;},&NBSP;HANDLEERROR); }



So far, we can apply the promise pattern to a single Ajax request, and it does not seem to show the promise advantage. Here's a look at concurrent collaboration for multiple AJAX requests. At this point, we need another method when to store the promise object that is ready to be invoked. Once a promise has been converted to a complete or rejected state, the corresponding handler function in the then method is invoked. The When method is critical when you need to wait for all operations to complete.

Promise.when = function () {/
* handle promises arguments and queue each *
/};



For example, just get IE10 and IE9 two pieces of content, we can write code like this:

var container, promise1, promise2; container = 
document.getElementById (' container ');
Promise1 = searchtwitter (' #IE10 ');
Promise2 = searchtwitter (' #IE9 '); Promise.when (PROMISE1,&NBSP;PROMISE2). Then (function  (DATA1,&NBSP;DATA2)  {    /*  reshuffle due to date */    var totalResults = 
Concatresults (Data1.results, data2.results);     totalresults.foreach function  (tweet)  {      
  var el = document.createelement (' Li ');
        el.innerText = tweet.text;
        container.appendchild (EL);
    }); }, handleerror); 



Analyze the above code to know that the When function waits for the state of two promise objects to change and then do the specific processing. In the actual promise library, when functions have many variants, such as When.some (), When.all (), When.any (), and so on, the reader can guess some meaning from the function name, Detailed instructions can refer to the commonjs of a promise implementation when.js.

In addition to COMMONJS, other mainstream JavaScript frameworks such as jquery, Dojo, and so on have their own promise implementations. Developers should take advantage of this pattern to reduce the complexity of asynchronous programming. Let's take dojo for example and look at the similarities and differences in its implementation. The object that implements the promise pattern in the

Dojo Framework is deferred, which also has then functions for processing completion and rejection states and supports concatenation, as well as resolve and reject, as described earlier. The following code completes the Twitter scenario:

Function&nbsp;searchtwitter (term) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;url,&nbsp;xhr,&nbsp;results,&nbsp;def
; &nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;=&nbsp; ' http://search.twitter.com/search.json?rpp=100&amp;q= ' &nbsp;+&nbsp;
Term &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;=&nbsp;new&nbsp;dojo.
Deferred ();
&nbsp;&nbsp;&nbsp;&nbsp;xhr&nbsp;=&nbsp;new&nbsp;xmlhttprequest ();
&nbsp;&nbsp;&nbsp;&nbsp;xhr.open (' Get ', &nbsp;url,&nbsp;true); &nbsp;&nbsp;&nbsp;&nbsp;xhr.onload&nbsp;=&nbsp;function&nbsp; (e) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if&nbsp; (this.status&nbsp;===&nbsp;200) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;results&nbsp;=&nbsp;json.parse (This.responsetext);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def.resolve (results);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;xhr.onerror&nbsp;=&nbsp;function&nbsp; (e) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbSp;def.reject (e);
&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;xhr.send ();
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;def; } dojo.ready (function&nbsp; () &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;container&nbsp;=&nbsp;dojo.byid ('
Container '); &nbsp;&nbsp;&nbsp;&nbsp;searchtwitter (' #IE10 '). Then (function&nbsp; (data) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;data.results.foreach function&nbsp; (tweet) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dojo.create (' Li ', &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;innerhtml:&nbsp;tweet.text &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;container);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});
&nbsp;&nbsp;&nbsp;&nbsp;}); });



Not only that, a similar Dojo.xhrget method returns the Dojo.deferred object, so there is no need to wrap the Promise mode yourself.

var deferred = dojo.xhrget ({
URL: "Search.json",
handleas: "JSON"
});
Deferred.then (function (data) {/
* handle results/
}, function (Error) {/
* handle error */
});



In addition, Dojo introduced Dojo.deferredlist, which enables developers to handle multiple dojo at the same time. Deferred object, which is actually another manifestation of the When method mentioned above.

Dojo.require ("Dojo.")
Deferredlist ");
Dojo.ready (function&nbsp; () &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;container,&nbsp;def1,&nbsp;def2,&nbsp;defs;
&nbsp;&nbsp;&nbsp;&nbsp;container&nbsp;=&nbsp;dojo.byid (' container ');
&nbsp;&nbsp;&nbsp;&nbsp;def1&nbsp;=&nbsp;searchtwitter (' #IE10 ');
&nbsp;&nbsp;&nbsp;&nbsp;def2&nbsp;=&nbsp;searchtwitter (' #IE9 '); &nbsp;&nbsp;&nbsp;&nbsp;defs&nbsp;=&nbsp;new&nbsp;dojo.
Deferredlist ([Def1,&nbsp;def2]); &nbsp;&nbsp;&nbsp;&nbsp;defs.then (function&nbsp; (data) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/ /&nbsp;handle&nbsp;exceptions &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (!results[0][0]&nbsp;| | &nbsp;!results[1][0]) &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dojo.create ("Li", &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;innerHTML:&nbsp; ' an&nbsp;error&nbsp;occurred ' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;},&nbsP;container);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;
Totalresults&nbsp;=&nbsp;concatresults (Data[0][1].results,&nbsp;data[1][1].results); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;totalresults.foreach function&nbsp; (tweet) &nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dojo.create ("Li", &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;innerhtml:&nbsp;tweet.text &nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;container);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});
&nbsp;&nbsp;&nbsp;&nbsp;}); });



The above code is more clear and no longer detailed.

Here, the reader may have a more complete understanding of the Promise model, asynchronous programming will become more and more important, in this case, we need to find ways to reduce complexity, promise model is a good example, its style is more humane, And the mainstream JS framework provides its own implementation. So in programming practice, developers should try this handy programming technique. It should be noted that the use of the promise pattern requires that the promise object be appropriately set, the state conversion function is invoked in the corresponding event, and the Promise object is returned at the end. The focus of the

Technology community on asynchronous programming is also heating up and the domestic community is making its own sound. Senior Technical expert Lao Zhao released a set of open source asynchronous development Auxiliary Library Jscex, its design is very ingenious, discard the callback function programming way, adopt a kind of "linear Code, asynchronous execution" idea.

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: 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.