Future.prototype 上的辅助方法

timeout 方法

  1. Future.prototype.timeout(duration[, reason])

创建一个新的 promise 对象,当超过设定的时间 duration(单位毫秒),源 promise 对象如果还未被设置为成功(fulfilled)或失败(rejected),则新的 promise 对象被设置为一个 TimeoutError 或者自定义的 reason。否则,其值跟源 promise 相同。

  1. var Future = hprose.Future;
  2.  
  3. var add = Future.wrap(function(a, b) {
  4. return a + b;
  5. });
  6.  
  7. var log = Future.wrap(console.log, console);
  8.  
  9. var p1 = Future.delayed(200, 3).timeout(300);
  10. var p2 = Future.delayed(500, 3).timeout(300);
  11.  
  12. log(add(p1, 2)).catch(log);
  13. log(add(p2, 5)).catch(log);

输出结果为:


  1. 5
  2. { [TimeoutError: timeout] message: 'timeout', name: 'TimeoutError' }

delay 方法

  1. Future.prototype.delay(duration)

创建一个新的 promise 对象,当经过 duration 毫秒后,该 promise 对象的值将被设置为跟源 promise 对象相同的成功值。如果源 promise 对象被设置为失败(rejected)状态,新的 promise 对象将立即被设为相同的失败原因,而无等待。

  1. var Future = hprose.Future;
  2.  
  3. var add = Future.wrap(function(a, b) {
  4. return a + b;
  5. });
  6.  
  7. var log = Future.wrap(console.log, console);
  8.  
  9. var p = Future.value(3);
  10. var p1 = p.delay(200).timeout(300);
  11. var p2 = p.delay(500).timeout(300);
  12.  
  13. log(add(p1, 2)).catch(log);
  14. log(add(p2, 5)).catch(log);

输出结果为:


  1. 5
  2. { [TimeoutError: timeout] message: 'timeout', name: 'TimeoutError' }

tap 方法

  1. Future.prototype.tap(onfulfilledSideEffect[, thisArg])

以下两种写法是等价的:

  1. promise.then(function(result) {
  2. onfulfilledSideEffect.call(thisArg, result);
  3. return result;
  4. });
  5.  
  6. promise.tap(onfulfilledSideEffect, thisArg);

spread 方法

  1. Future.prototype.spread(onfulfilledArray[, thisArg])

以下两种写法是等价的:

  1. promise.then(function(array) {
  2. return onfulfilledArray.apply(thisArg, array);
  3. });
  4.  
  5. promise.spread(onfulfilledArray, thisArg);

get 方法

  1. Future.prototype.get(key)

以下两种写法是等价的:

  1. promise.then(function(result) {
  2. return result[key];
  3. });
  4.  
  5. promise.get(key);

set 方法

  1. Future.prototype.set(key, value)

以下两种写法是等价的:

  1. promise.then(function(result) {
  2. result[key] = value;
  3. return result;
  4. });
  5.  
  6. promise.set(key, value);

下面我们来看一个例子:

  1. var Future = hprose.Future;
  2.  
  3. function User() {
  4. this.name = "Tom";
  5. this.age = 18;
  6. }
  7.  
  8. var log = Future.wrap(console.log, console);
  9.  
  10. var p = Future.value(new User());
  11.  
  12. p.get('name').then(function(result) { console.log(result); });
  13. log(p.get('age'));
  14. p.set('password', 'hprose')
  15. .tap(log)
  16. .tap(function(result) { console.log(result); })
  17. .set('password', 'I love hprose!')
  18. .get('password')
  19. .then(log);

输出结果:


  1. Tom
  2. { name: 'Tom', age: 18, password: 'hprose' }
  3. 18
  4. { name: 'Tom', age: 18, password: 'I love hprose!' }
  5. I love hprose!

注意上面的结果中,被 Future.wrap 包装过的 log 函数在执行时,并不是按照代码书写顺序执行的,也不是按照链式调用顺序执行的,它比在代码中书写的位置执行的要晚,因为被包装过的函数本身也是异步执行的,因此在输出结果上会比较反直觉。

比如上面输出结果中的这一句:


  1. { name: 'Tom', age: 18, password: 'I love hprose!' }

实际上是这一句代码:

  1. .tap(log)

输出的。

因此,在链式调用中使用 Future.wrap 包装过的函数,一定要注意这点。后面介绍的 bind 方法也同样需要注意这个问题。

apply 方法

  1. Future.prototype.apply(method[, args])

异步执行当前 promise 对象上的方法名为 method 的方法,参数为 args 数组中的元素,返回结果为包含了执行结果的 promise 对象。其中参数数组中的元素也可以为 promise 对象,在执行时,会带入这些 promise 对象所包含的成功值,如果这些 promise 对象中包含有失败状态的,则 method 方法不会执行,返回的 promise 对象中包含的失败原因为第一个变为失败(rejected)状态的参数的失败原因。

例如:

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var p = Future.value([]);
  6.  
  7. p.apply('push', ['banana', Future.value('apple'), 'peach'])
  8. .then(function(length) {
  9. console.log(length);
  10. log(p);
  11. });
  12.  
  13. p.apply('push', ['banana', Future.error('apple'), 'peach'])
  14. .catch(function(reason) {
  15. console.log(reason);
  16. });

输出结果为:


  1. apple
  2. 3
  3. [ 'banana', 'apple', 'peach' ]

因为第二个 apply 的参数中包含有失败(rejected)状态的 promise 参数,因此第二个 apply 中的 push 方法并没有执行而提前返回,所以失败原因 apple 被先显示出来。

call 方法

  1. Future.prototype.call(method[, arg1[, arg2[, arg3...]]])

与上面的 apply 方法类似,唯一不同的是参数。看下面的例子:

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var p = Future.value([]);
  6.  
  7. p.call('push', 'banana', Future.value('apple'), 'peach')
  8. .then(function(length) {
  9. console.log(length);
  10. log(p);
  11. });
  12.  
  13. p.call('push', 'banana', Future.error('apple'), 'peach')
  14. .catch(function(reason) {
  15. console.log(reason);
  16. });

执行结果与上面的 apply 的例子执行结果相同。

bind 方法

  1. Future.prototype.bind(method[, arg1[, arg2[, arg3...]]])
  2. Future.prototype.bind(methods[, arg1[, arg2[, arg3...]]])

bind 方法可以将当前 promise 对象所包含的成功值上的一个或多个方法及其参数绑定到当前的 promise 对象上。其中参数可以是 promise 对象,且绑定之后的方法在调用时也支持 promise 对象参数,返回值也为 promise 对象。例如:

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var p = Future.value([]);
  6. p.bind('push');
  7.  
  8. p.push('banana', Future.value('apple'), 'peach')
  9. .then(function(length) {
  10. console.log(length);
  11. log(p);
  12. });
  13.  
  14. p.push('banana', Future.error('apple'), 'peach')
  15. .catch(function(reason) {
  16. console.log(reason);
  17. });
  18.  
  19. var p2 = Future.value(new Date());
  20. p2.bind(Object.getOwnPropertyNames(Date.prototype));
  21.  
  22. log(p2.toString());
  23. p2.setFullYear(1980).then(function() {
  24. log(p2.toString());
  25. });

运行结果如下:


  1. apple
  2. 3
  3. Tue Jul 28 2015 20:51:47 GMT+0800 (CST)
  4. [ 'banana', 'apple', 'peach' ]
  5. Mon Jul 28 1980 20:51:47 GMT+0800 (CST)

forEach 方法

  1. Future.prototype.forEach(callback[, thisArg])

该方法是 Array.prototype.forEachpromise 版本。它与 Array.prototype.forEach 的区别跟 Future.forEachArray.forEach 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. function logArrayElements(element, index, array) {
  4. console.log('a[' + index + '] = ' + element);
  5. }
  6.  
  7. var p = Future.value([2, Future.value(5), , 9]);
  8. // Note elision, there is no member at 2 so it isn't visited
  9. p.forEach(logArrayElements);

输出结果为:


  1. a[0] = 2
  2. a[1] = 5
  3. a[3] = 9

every 方法

  1. Future.prototype.every(callback[, thisArg])

该方法是 Array.prototype.everypromise 版本。它与 Array.prototype.every 的区别跟 Future.everyArray.every 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. function isBigEnough(element, index, array) {
  6. return element >= 10;
  7. }
  8.  
  9. var a1 = Future.value([12, Future.value(5), 8, Future.value(130), 44]);
  10. var a2 = Future.value([12, Future.value(54), 18, Future.value(130), 44]);
  11. var a3 = Future.value(a1);
  12. var a4 = Future.value(a2);
  13. log(a1.every(isBigEnough)); // false
  14. log(a2.every(isBigEnough)); // true
  15. log(a3.every(isBigEnough)); // false
  16. log(a4.every(isBigEnough)); // true

输出结果为:


  1. false
  2. true
  3. false
  4. true

some 方法

  1. Future.prototype.some(callback[, thisArg])

该方法是 Array.prototype.somepromise 版本。它与 Array.prototype.some 的区别跟 Future.someArray.some 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. function isBiggerThan10(element, index, array) {
  6. return element > 10;
  7. }
  8.  
  9. var a1 = Future.value([2, Future.value(5), 8, Future.value(1), 4]);
  10. var a2 = Future.value([12, Future.value(5), 8, Future.value(1), 4]);
  11. var a3 = Future.value(a1);
  12. var a4 = Future.value(a2);
  13. log(a1.some(isBiggerThan10)); // false
  14. log(a2.some(isBiggerThan10)); // true
  15. log(a3.some(isBiggerThan10)); // false
  16. log(a4.some(isBiggerThan10)); // true

输出结果为:


  1. false
  2. true
  3. false
  4. true

filter 方法

  1. Future.prototype.filter(callback[, thisArg])

该方法是 Array.prototype.filterpromise 版本。它与 Array.prototype.filter 的区别跟 Future.filterArray.filter 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. function isBigEnough(value) {
  6. return value >= 10;
  7. }
  8.  
  9. var p = Future.value([12, Future.value(5), 8, Future.value(130), 44]);
  10. log(p.filter(isBigEnough));

输出结果为:


  1. [ 12, 130, 44 ]

map 方法

  1. Future.prototype.map(callback[, thisArg])

该方法是 Array.prototype.mappromise 版本。它与 Array.prototype.map 的区别跟 Future.mapArray.map 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var p = Future.value([1, Future.value(4), Future.value(9)]);
  6. log(p.map(Math.sqrt));
  7. log(p.map(function(num) {
  8. return num * 2;
  9. }));

输出结果为:


  1. [ 1, 2, 3 ]
  2. [ 2, 8, 18 ]

reduce 方法

  1. Future.prototype.reduce(callback[, initialValue])

该方法是 Array.prototype.reducepromise 版本。它与 Array.prototype.reduce 的区别跟 Future.reduceArray.reduce 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var p = Future.value([Future.value(0), 1, Future.value(2), 3, Future.value(4)]);
  6.  
  7. function callback(previousValue, currentValue, index, array) {
  8. return previousValue + currentValue;
  9. }
  10.  
  11. log(p.reduce(callback));
  12. log(p.reduce(callback, 10));
  13. log(p.reduce(callback, Future.value(20)));

输出结果为:


  1. 10
  2. 20
  3. 30

reduceRight 方法

  1. Future.prototype.reduceRight(callback[, initialValue])

该方法是 Array.prototype.reduceRightpromise 版本。它与 Array.prototype.reduceRight 的区别跟 Future.reduceRightArray.reduceRight 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. function concat(a, b) {
  6. return a.concat(b);
  7. }
  8.  
  9. var p = Future.value([[0, 1], Future.value([2, 3]), Future.value([4, 5])]);
  10.  
  11. log(p.reduceRight(concat, []));
  12. log(p.reduceRight(concat, Future.value([6, 7])));

输出结果为:


  1. [ 4, 5, 2, 3, 0, 1 ]
  2. [ 6, 7, 4, 5, 2, 3, 0, 1 ]

indexOf 方法

  1. Future.prototype.indexOf(searchElement[, fromIndex])

该方法是 Array.prototype.indexOfpromise 版本。它与 Array.prototype.indexOf 的区别跟 Future.indexOfArray.indexOf 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var array = Future.value([1, Future.value(2), Future.value(3)]);
  6.  
  7. log(array.indexOf(2));
  8. log(array.indexOf(Future.value(3), 1));
  9. log(array.indexOf(1, 1));

输出结果为:


  1. 1
  2. 2
  3. -1

lastIndexOf 方法

  1. Future.prototype.lastIndexOf(searchElement[, fromIndex])

该方法是 Array.prototype.lastIndexOfpromise 版本。它与 Array.prototype.lastIndexOf 的区别跟 Future.lastIndexOfArray.lastIndexOf 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var array = Future.value([1, Future.value(2), Future.value(3)]);
  6.  
  7. log(array.lastIndexOf(2));
  8. log(array.lastIndexOf(Future.value(3), 1));
  9. log(array.lastIndexOf(1, 1));

输出结果为:


  1. 1
  2. -1
  3. 0

includes 方法

  1. Future.prototype.includes(searchElement[, fromIndex])

该方法是 Array.prototype.includespromise 版本。它与 Array.prototype.includes 的区别跟 Future.includesArray.includes 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. var array = Future.value([1, Future.value(2), Future.value(3)]);
  6.  
  7. log(array.includes(2));
  8. log(array.includes(Future.value(3), 1));
  9. log(array.includes(1, 1));

输出结果为:


  1. true
  2. true
  3. false

find 方法

  1. Future.prototype.find(predicate[, thisArg])

该方法是 Array.prototype.findpromise 版本。它与 Array.prototype.find 的区别跟 Future.findArray.find 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. function isPrime(element, index, array) {
  6. var start = 2;
  7. while (start <= Math.sqrt(element)) {
  8. if (element % start++ < 1) {
  9. return false;
  10. }
  11. }
  12. return element > 1;
  13. }
  14.  
  15. var array1 = Future.value([4, Future.value(6), 8, Future.value(12)]);
  16. var array2 = Future.value([4, Future.value(5), 7, Future.value(12)]);
  17.  
  18. log(array1.find(isPrime));
  19. log(array2.find(isPrime));

输出结果为:


  1. undefined
  2. 5

findIndex 方法

  1. Future.prototype.findIndex(predicate[, thisArg])

该方法是 Array.prototype.findIndexpromise 版本。它与 Array.prototype.findIndex 的区别跟 Future.findIndexArray.findIndex 的区别相同。

  1. var Future = hprose.Future;
  2.  
  3. var log = Future.wrap(console.log, console);
  4.  
  5. function isPrime(element, index, array) {
  6. var start = 2;
  7. while (start <= Math.sqrt(element)) {
  8. if (element % start++ < 1) {
  9. return false;
  10. }
  11. }
  12. return element > 1;
  13. }
  14.  
  15. var array1 = Future.value([4, Future.value(6), 8, Future.value(12)]);
  16. var array2 = Future.value([4, Future.value(5), 7, Future.value(12)]);
  17.  
  18. log(array1.findIndex(isPrime));
  19. log(array2.findIndex(isPrime));

输出结果为:

  1. -1
  2. 1