Follow the previous "One Promise Practice: Asynchronous Task grouping scheduling", this time is also from the work of the actual problems encountered.
This encounter problem can be likened to a batch of raw materials processing, wherein the beginning of some of the process is the same, like the assembly line, the beginning of a paragraph is the same, the back is divided into two streams, on this basis, respectively, the production of different products.
o--o--o Product 1 / raw o--o--o--o o--o--o product 2
The raw material here is the raw data to be processed, which can be represented by an array:
var raw = [1, 2, 3, 4, 5]
Each raw data should be processed after the public part is treated:
[Comm (1), Comm (2), Comm (3), Comm (4), Comm (5)]
After two lines are processed separately should get:
P1 = [P1 (comm (1)), P1 (Comm (2)), P1 (Comm (3)), P1 (Comm (4)), P1 (Comm (5= [P2 (comm (1)), P2 (Comm (2)), P2 (Comm (3)), p2 (Comm (4)), P2 (Comm (5))]
Scenario 1: With the last experience, I want to do the work by dynamically creating a series of then chains, using two promise objects to save the final result of two lines:
varMain =promise.resolve ()varBranch1 =promise.resolve ([])varBRANCH2 =promise.resolve ([])varlist = [1, 2, 3, 4, 5]list.foreach (function(ID) {main= Main.then (function () {return"Comm (" + ID + ")"}). Then (function(comm) {Branch1=Branch1.then (path1 (comm)) Branch2=Branch2.then (path2 (comm))}) SetTimeout (function() {Branch1.then (function(Final) {Console.log ("Branch1:") Console.log (Final)}) Branch2.then (function(Final) {Console.log ("BRANCH2:") Console.log (Final)}),0)functionpath2 (ID) {return function(prev) {varret = "Bran2 (" + ID + ")"Prev.push (ret)returnprev}}functionpath1 (ID) {return function(prev) {varret = "Bran1 (" + ID + ")"Prev.push (ret)returnprev}}
Printing results:
' Bran1 (Comm (1)) ', ' Bran1 (Comm (2) ', ' Bran1 (Comm ( 3) ') ', ' Bran1 (Comm (4) ') ' , ' Bran1 (Comm (5)) "bran2 (Comm (1)) ', ' Bran2 (Comm (2)) ', ' Bran2 (Comm (3)) ' , ' Bran2 (Comm (4)) ', ' Bran2 (Comm (5)) ']
It is important to note that you need to use settimeout when collecting the results of branch1 and BRANCH2. My limited understanding of runtime is to ensure that the callback function is not added to the event queue in this tick because those processes in foreach need to be performed prior to the collection process.
This makes it clear that the data on the two lines are stored in two promise objects, which looks very pleasant.
Scenario two, do not use the Promise object to save the results
varTotal = []varP1R = []varP2R =[]list.foreach (function(ID) {main= Main.then (function() { return"Comm (" + ID + ")"}). Then (function(comm) {varPromises =[Path1 (Comm), path2 (comm)]returnPromise.all (promises)}) . Then (function(re) {Total.push (RE)})}) G.then (function() {Total.foreach (function(e) {P1r.push (e[0]) P2r.push (e[1])}) Console.log ("P1") Console.log (p1r) Console.log ("P2") Console.log (P2R)})functionpath1 (d) {returnPromise.resolve ("P1 (" + D + ")")}functionpath2 (d) {returnPromise.resolve ("P2 (" + D + ")")}
This method is in fact similar to the scheme, except that no more than two promise objects are used, but a normal array is used. Then the operations of the different branches are performed using Promise.all, and the final result is a little bit of processing. The advantage is that there is no more settimeout.
Scenario three, using recursion
functionC (list) {varReta = [] varRETB = [] return(function() { if(!list | | list.length = = 0)return[Reta, Retb]varFunc =Arguments.callee, head=List.shift ()returnPromise.resolve ("Common (" + head + ")"). Then (function(comm) {returnPromise.all ([Resolvea (Comm), RESOLVEB (comm)])}) . Then (function(ret) {Reta.push (ret[0]) Retb.push (ret[1]) returnfunc (list)}) })()}functionResolvea (d) {returnPromise.resolve ("P1 (" + D + ")")} functionResolveb (d) {returnPromise.resolve ("P2 (" + D + ")")}
Call:
C ([1, 2, 3, 4, 5]). Then (function (e) { console.log (e)})
Results:
[[' P1 (Common (1)] ', ' P1 (Common (2) ', ' P1 (Common ( 3) ', ' P1 (Common (4) ') ' , ' P1 (Common (5)) ' , ' P2 (Common (1) ', ' P2 (Common (2)) ', ' P2 (Common (3)) ', ' P2 (Common (4)) ', ' P2 (Common (5)) ']
The third scenario is actually a recursive version of scenario two, but more concise than scenario two, the introduction of recursion makes the code very short.
Think: How do I add more branches? Can the entire process be modularized and framed? Which option is easier to expand? (I'm personally inclined to use scenario one because I can go on and then after I finally get two promise objects ...) )
One promise Practice (2): Reuse of DataPath