Browse Source

then: destructures an array result in case of 2+ arg block

Herbert Vojčík 8 years ago
parent
commit
2d961cc87d
3 changed files with 33 additions and 55 deletions
  1. 0 16
      API-CHANGES.txt
  2. 13 30
      src/Kernel-Promises.js
  3. 20 9
      src/Kernel-Promises.st

+ 0 - 16
API-CHANGES.txt

@@ -11,14 +11,6 @@
   + then:catch:
   + then:on:do:
   + then:on:do:catch:
-  + all:
-  + all:catch:
-  + all:on:do:
-  + all:on:do:catch:
-  + all:then:
-  + all:then:catch:
-  + all:then:on:do:
-  + all:then:on:do:catch:
 + JSObjectProxy >>
   + catch:
   + on:do:
@@ -27,14 +19,6 @@
   + then:catch:
   + then:on:do:
   + then:on:do:catch:
-  + all:
-  + all:catch:
-  + all:on:do:
-  + all:on:do:catch:
-  + all:then:
-  + all:then:catch:
-  + all:then:on:do:
-  + all:then:on:do:catch:
 
 
 0.14.18:

+ 13 - 30
src/Kernel-Promises.js

@@ -8,32 +8,6 @@ $core.addClass('Thenable', $globals.Object, [], 'Kernel-Promises');
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.Thenable.comment="I am the abstract base class for Promises.\x0a\x0aMy subclasses should wrap existing JS implementations.\x0a\x0aI contain methods that wrap Promises/A+ `.then` behaviour.";
 //>>excludeEnd("ide");
-$core.addMethod(
-$core.method({
-selector: "all:",
-protocol: 'promises',
-fn: function (nadicBlock){
-var self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-return self.then(function (array) {
-    return nadicBlock._valueWithPossibleArguments_(array);
-});
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"all:",{nadicBlock:nadicBlock},$globals.Thenable)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["nadicBlock"],
-source: "all: nadicBlock\x0a<return self.then(function (array) {\x0a    return nadicBlock._valueWithPossibleArguments_(array);\x0a})>",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.Thenable);
-
 $core.addMethod(
 $core.method({
 selector: "catch:",
@@ -126,9 +100,18 @@ return $core.withContext(function($ctx1) {
 
 var array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];
 return array.reduce(function (soFar, aBlock) {
-    return soFar.then(function (result) {
-        return aBlock._value_(result);
-    });
+    return soFar.then(typeof aBlock === "function" && aBlock.length > 1 ?
+        function (result) {
+            if (Array.isArray(result)) {
+                return aBlock._valueWithPossibleArguments_([result].concat(result.slice(0, aBlock.length-1)));
+            } else {
+                return aBlock._value_(result);
+            }
+        } :
+        function (result) {
+            return aBlock._value_(result);
+        }
+    );
 }, self);
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -137,7 +120,7 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aBlockOrArray"],
-source: "then: aBlockOrArray\x0a<\x0avar array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];\x0areturn array.reduce(function (soFar, aBlock) {\x0a    return soFar.then(function (result) {\x0a        return aBlock._value_(result);\x0a    });\x0a}, self)>",
+source: "then: aBlockOrArray\x0a\x22Accepts a block or array of blocks.\x0aEach of blocks in the array or the singleton one is\x0aused in .then call to a promise, to accept a result\x0aand transform it to the result for the next one.\x0aIn case a block has more than one argument\x0aand result is an array, first n-1 elements of the array\x0aare put into additional arguments beyond the first.\x0aThe first argument always contains the result as-is.\x22\x0a<\x0avar array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];\x0areturn array.reduce(function (soFar, aBlock) {\x0a    return soFar.then(typeof aBlock === \x22function\x22 && aBlock.length >> 1 ?\x0a        function (result) {\x0a            if (Array.isArray(result)) {\x0a                return aBlock._valueWithPossibleArguments_([result].concat(result.slice(0, aBlock.length-1)));\x0a            } else {\x0a                return aBlock._value_(result);\x0a            }\x0a        } :\x0a        function (result) {\x0a            return aBlock._value_(result);\x0a        }\x0a    );\x0a}, self)>",
 referencedClasses: [],
 //>>excludeEnd("ide");
 messageSends: []

+ 20 - 9
src/Kernel-Promises.st

@@ -11,12 +11,6 @@ I contain methods that wrap Promises/A+ `.then` behaviour.!
 
 !Thenable methodsFor: 'promises'!
 
-all: nadicBlock
-<return self.then(function (array) {
-    return nadicBlock._valueWithPossibleArguments_(array);
-})>
-!
-
 catch: aBlock
 <return self.then(null, function (err) {
     return aBlock._value_(err);
@@ -38,12 +32,29 @@ on: aClass do: aBlock catch: anotherBlock
 !
 
 then: aBlockOrArray
+"Accepts a block or array of blocks.
+Each of blocks in the array or the singleton one is
+used in .then call to a promise, to accept a result
+and transform it to the result for the next one.
+In case a block has more than one argument
+and result is an array, first n-1 elements of the array
+are put into additional arguments beyond the first.
+The first argument always contains the result as-is."
 <
 var array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];
 return array.reduce(function (soFar, aBlock) {
-    return soFar.then(function (result) {
-        return aBlock._value_(result);
-    });
+    return soFar.then(typeof aBlock === "function" && aBlock.length >> 1 ?
+        function (result) {
+            if (Array.isArray(result)) {
+                return aBlock._valueWithPossibleArguments_([result].concat(result.slice(0, aBlock.length-1)));
+            } else {
+                return aBlock._value_(result);
+            }
+        } :
+        function (result) {
+            return aBlock._value_(result);
+        }
+    );
 }, self)>
 !