Javascript:自分で非同期プロセスのプログラミングフレームを書きます.

10432 ワード

背景
NodeJsが出てきてから、非同期プログラムはより体系化され、フレームワークの話をしました.非同期プログラミングフレームワークによる深層ネスティング問題に対応するために、コミュニティにも非同期プロセスプログラミングフレームが現れました.
コードを配合しました
 1 var Asy = function () {
 2 };
 3 
 4 Asy.start = function (action, success, failure) {
 5     var asy = new Asy();
 6     asy._addAction(action, success, failure);
 7 
 8     return asy;
 9 }
10 
11 Asy.emptyFun = function () { };
12 
13 Asy.prototype.then = function (action, success, failure) {
14     var me = this;
15 
16     me._addAction(action, success, failure);
17 
18     return me;
19 };
20 
21 Asy.prototype._addAction = function (action, success, failure) {
22     var me = this;
23 
24     me._actions = me._actions || [];
25 
26     me._actions.push({
27         action: action || Asy.emptyFun,
28         success: success || Asy.emptyFun,
29         failure: failure || Asy.emptyFun
30     });
31 };
32 
33 Asy.prototype.execute = function () {
34     var me = this;
35 
36     var length = me._actions.length;
37 
38     var resultFun = function () {
39         var args = Array.prototype.slice.call(arguments)
40                                   .concat([me._actions[length - 1].success, me._actions[length - 1].failure])
41 
42         me._actions[length - 1].action.apply(null, args);
43     };
44 
45     for (var i = me._actions.length - 2; i >= 0 ; i--) {
46         (function (action) {
47             var oldResultFun = resultFun;
48 
49             resultFun = function () {
50                 var newSuccess = function () {
51                     var args = Array.prototype.slice.call(arguments);
52                     action.success.apply(null, args);
53                     oldResultFun.apply(null, args);
54                 };
55 
56                 var args = Array.prototype.slice.call(arguments)
57                                           .concat([newSuccess, action.failure]);
58 
59                 action.action.apply(null, args);
60             };
61         })(me._actions[i]);
62     };
63 
64     var args = Array.prototype.slice.call(arguments);
65     resultFun.apply(null, args);
66 }
67 
68 var testAsyFun = function (i, success, failure) {
69     setTimeout(function () {
70         i = i + 1;
71 
72         success(i);
73     }, 2000);
74 };
75 
76 Asy
77    .start(testAsyFun, function (i) {
78        console.log("A:" + i);
79    })
80    .then(testAsyFun, function (i) {
81        console.log("B:" + i)
82    })
83    .then(testAsyFun, function (i) {
84        console.log("C:" + i)
85    })
86    //.wait([testAsyFun], [testAsyFun], function () {
87 
88    //})
89    .execute(1);