Future.prototype 上的辅助方法
timeout 方法
- Future.prototype.timeout(duration[, reason])
创建一个新的 promise
对象,当超过设定的时间 duration
(单位毫秒),源 promise
对象如果还未被设置为成功(fulfilled)或失败(rejected),则新的 promise
对象被设置为一个 TimeoutError
或者自定义的 reason
。否则,其值跟源 promise
相同。
- var Future = hprose.Future;
- var add = Future.wrap(function(a, b) {
- return a + b;
- });
- var log = Future.wrap(console.log, console);
- var p1 = Future.delayed(200, 3).timeout(300);
- var p2 = Future.delayed(500, 3).timeout(300);
- log(add(p1, 2)).catch(log);
- log(add(p2, 5)).catch(log);
输出结果为:
5
{ [TimeoutError: timeout] message: 'timeout', name: 'TimeoutError' }
delay 方法
- Future.prototype.delay(duration)
创建一个新的 promise
对象,当经过 duration
毫秒后,该 promise
对象的值将被设置为跟源 promise
对象相同的成功值。如果源 promise
对象被设置为失败(rejected)状态,新的 promise
对象将立即被设为相同的失败原因,而无等待。
- var Future = hprose.Future;
- var add = Future.wrap(function(a, b) {
- return a + b;
- });
- var log = Future.wrap(console.log, console);
- var p = Future.value(3);
- var p1 = p.delay(200).timeout(300);
- var p2 = p.delay(500).timeout(300);
- log(add(p1, 2)).catch(log);
- log(add(p2, 5)).catch(log);
输出结果为:
5
{ [TimeoutError: timeout] message: 'timeout', name: 'TimeoutError' }
tap 方法
- Future.prototype.tap(onfulfilledSideEffect[, thisArg])
以下两种写法是等价的:
- promise.then(function(result) {
- onfulfilledSideEffect.call(thisArg, result);
- return result;
- });
- promise.tap(onfulfilledSideEffect, thisArg);
spread 方法
- Future.prototype.spread(onfulfilledArray[, thisArg])
以下两种写法是等价的:
- promise.then(function(array) {
- return onfulfilledArray.apply(thisArg, array);
- });
- promise.spread(onfulfilledArray, thisArg);
get 方法
- Future.prototype.get(key)
以下两种写法是等价的:
- promise.then(function(result) {
- return result[key];
- });
- promise.get(key);
set 方法
- Future.prototype.set(key, value)
以下两种写法是等价的:
- promise.then(function(result) {
- result[key] = value;
- return result;
- });
- promise.set(key, value);
下面我们来看一个例子:
- var Future = hprose.Future;
- function User() {
- this.name = "Tom";
- this.age = 18;
- }
- var log = Future.wrap(console.log, console);
- var p = Future.value(new User());
- p.get('name').then(function(result) { console.log(result); });
- log(p.get('age'));
- p.set('password', 'hprose')
- .tap(log)
- .tap(function(result) { console.log(result); })
- .set('password', 'I love hprose!')
- .get('password')
- .then(log);
输出结果:
Tom
{ name: 'Tom', age: 18, password: 'hprose' }
18
{ name: 'Tom', age: 18, password: 'I love hprose!' }
I love hprose!
注意上面的结果中,被 Future.wrap
包装过的 log
函数在执行时,并不是按照代码书写顺序执行的,也不是按照链式调用顺序执行的,它比在代码中书写的位置执行的要晚,因为被包装过的函数本身也是异步执行的,因此在输出结果上会比较反直觉。
比如上面输出结果中的这一句:
{ name: 'Tom', age: 18, password: 'I love hprose!' }
实际上是这一句代码:
- .tap(log)
输出的。
因此,在链式调用中使用 Future.wrap
包装过的函数,一定要注意这点。后面介绍的 bind
方法也同样需要注意这个问题。
apply 方法
- Future.prototype.apply(method[, args])
异步执行当前 promise
对象上的方法名为 method
的方法,参数为 args
数组中的元素,返回结果为包含了执行结果的 promise
对象。其中参数数组中的元素也可以为 promise
对象,在执行时,会带入这些 promise
对象所包含的成功值,如果这些 promise
对象中包含有失败状态的,则 method
方法不会执行,返回的 promise
对象中包含的失败原因为第一个变为失败(rejected)状态的参数的失败原因。
例如:
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var p = Future.value([]);
- p.apply('push', ['banana', Future.value('apple'), 'peach'])
- .then(function(length) {
- console.log(length);
- log(p);
- });
- p.apply('push', ['banana', Future.error('apple'), 'peach'])
- .catch(function(reason) {
- console.log(reason);
- });
输出结果为:
apple
3
[ 'banana', 'apple', 'peach' ]
因为第二个 apply
的参数中包含有失败(rejected)状态的 promise
参数,因此第二个 apply
中的 push
方法并没有执行而提前返回,所以失败原因 apple
被先显示出来。
call 方法
- Future.prototype.call(method[, arg1[, arg2[, arg3...]]])
与上面的 apply
方法类似,唯一不同的是参数。看下面的例子:
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var p = Future.value([]);
- p.call('push', 'banana', Future.value('apple'), 'peach')
- .then(function(length) {
- console.log(length);
- log(p);
- });
- p.call('push', 'banana', Future.error('apple'), 'peach')
- .catch(function(reason) {
- console.log(reason);
- });
执行结果与上面的 apply
的例子执行结果相同。
bind 方法
- Future.prototype.bind(method[, arg1[, arg2[, arg3...]]])
- Future.prototype.bind(methods[, arg1[, arg2[, arg3...]]])
bind
方法可以将当前 promise
对象所包含的成功值上的一个或多个方法及其参数绑定到当前的 promise
对象上。其中参数可以是 promise
对象,且绑定之后的方法在调用时也支持 promise
对象参数,返回值也为 promise
对象。例如:
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var p = Future.value([]);
- p.bind('push');
- p.push('banana', Future.value('apple'), 'peach')
- .then(function(length) {
- console.log(length);
- log(p);
- });
- p.push('banana', Future.error('apple'), 'peach')
- .catch(function(reason) {
- console.log(reason);
- });
- var p2 = Future.value(new Date());
- p2.bind(Object.getOwnPropertyNames(Date.prototype));
- log(p2.toString());
- p2.setFullYear(1980).then(function() {
- log(p2.toString());
- });
运行结果如下:
apple
3
Tue Jul 28 2015 20:51:47 GMT+0800 (CST)
[ 'banana', 'apple', 'peach' ]
Mon Jul 28 1980 20:51:47 GMT+0800 (CST)
forEach 方法
- Future.prototype.forEach(callback[, thisArg])
该方法是 Array.prototype.forEach
的 promise
版本。它与 Array.prototype.forEach
的区别跟 Future.forEach
和 Array.forEach
的区别相同。
- var Future = hprose.Future;
- function logArrayElements(element, index, array) {
- console.log('a[' + index + '] = ' + element);
- }
- var p = Future.value([2, Future.value(5), , 9]);
- // Note elision, there is no member at 2 so it isn't visited
- p.forEach(logArrayElements);
输出结果为:
a[0] = 2
a[1] = 5
a[3] = 9
every 方法
- Future.prototype.every(callback[, thisArg])
该方法是 Array.prototype.every
的 promise
版本。它与 Array.prototype.every
的区别跟 Future.every
和 Array.every
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- function isBigEnough(element, index, array) {
- return element >= 10;
- }
- var a1 = Future.value([12, Future.value(5), 8, Future.value(130), 44]);
- var a2 = Future.value([12, Future.value(54), 18, Future.value(130), 44]);
- var a3 = Future.value(a1);
- var a4 = Future.value(a2);
- log(a1.every(isBigEnough)); // false
- log(a2.every(isBigEnough)); // true
- log(a3.every(isBigEnough)); // false
- log(a4.every(isBigEnough)); // true
输出结果为:
false
true
false
true
some 方法
- Future.prototype.some(callback[, thisArg])
该方法是 Array.prototype.some
的 promise
版本。它与 Array.prototype.some
的区别跟 Future.some
和 Array.some
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- function isBiggerThan10(element, index, array) {
- return element > 10;
- }
- var a1 = Future.value([2, Future.value(5), 8, Future.value(1), 4]);
- var a2 = Future.value([12, Future.value(5), 8, Future.value(1), 4]);
- var a3 = Future.value(a1);
- var a4 = Future.value(a2);
- log(a1.some(isBiggerThan10)); // false
- log(a2.some(isBiggerThan10)); // true
- log(a3.some(isBiggerThan10)); // false
- log(a4.some(isBiggerThan10)); // true
输出结果为:
false
true
false
true
filter 方法
- Future.prototype.filter(callback[, thisArg])
该方法是 Array.prototype.filter
的 promise
版本。它与 Array.prototype.filter
的区别跟 Future.filter
和 Array.filter
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- function isBigEnough(value) {
- return value >= 10;
- }
- var p = Future.value([12, Future.value(5), 8, Future.value(130), 44]);
- log(p.filter(isBigEnough));
输出结果为:
[ 12, 130, 44 ]
map 方法
- Future.prototype.map(callback[, thisArg])
该方法是 Array.prototype.map
的 promise
版本。它与 Array.prototype.map
的区别跟 Future.map
和 Array.map
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var p = Future.value([1, Future.value(4), Future.value(9)]);
- log(p.map(Math.sqrt));
- log(p.map(function(num) {
- return num * 2;
- }));
输出结果为:
[ 1, 2, 3 ]
[ 2, 8, 18 ]
reduce 方法
- Future.prototype.reduce(callback[, initialValue])
该方法是 Array.prototype.reduce
的 promise
版本。它与 Array.prototype.reduce
的区别跟 Future.reduce
和 Array.reduce
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var p = Future.value([Future.value(0), 1, Future.value(2), 3, Future.value(4)]);
- function callback(previousValue, currentValue, index, array) {
- return previousValue + currentValue;
- }
- log(p.reduce(callback));
- log(p.reduce(callback, 10));
- log(p.reduce(callback, Future.value(20)));
输出结果为:
10
20
30
reduceRight 方法
- Future.prototype.reduceRight(callback[, initialValue])
该方法是 Array.prototype.reduceRight
的 promise
版本。它与 Array.prototype.reduceRight
的区别跟 Future.reduceRight
和 Array.reduceRight
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- function concat(a, b) {
- return a.concat(b);
- }
- var p = Future.value([[0, 1], Future.value([2, 3]), Future.value([4, 5])]);
- log(p.reduceRight(concat, []));
- log(p.reduceRight(concat, Future.value([6, 7])));
输出结果为:
[ 4, 5, 2, 3, 0, 1 ]
[ 6, 7, 4, 5, 2, 3, 0, 1 ]
indexOf 方法
- Future.prototype.indexOf(searchElement[, fromIndex])
该方法是 Array.prototype.indexOf
的 promise
版本。它与 Array.prototype.indexOf
的区别跟 Future.indexOf
和 Array.indexOf
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var array = Future.value([1, Future.value(2), Future.value(3)]);
- log(array.indexOf(2));
- log(array.indexOf(Future.value(3), 1));
- log(array.indexOf(1, 1));
输出结果为:
1
2
-1
lastIndexOf 方法
- Future.prototype.lastIndexOf(searchElement[, fromIndex])
该方法是 Array.prototype.lastIndexOf
的 promise
版本。它与 Array.prototype.lastIndexOf
的区别跟 Future.lastIndexOf
和 Array.lastIndexOf
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var array = Future.value([1, Future.value(2), Future.value(3)]);
- log(array.lastIndexOf(2));
- log(array.lastIndexOf(Future.value(3), 1));
- log(array.lastIndexOf(1, 1));
输出结果为:
1
-1
0
includes 方法
- Future.prototype.includes(searchElement[, fromIndex])
该方法是 Array.prototype.includes
的 promise
版本。它与 Array.prototype.includes
的区别跟 Future.includes
和 Array.includes
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- var array = Future.value([1, Future.value(2), Future.value(3)]);
- log(array.includes(2));
- log(array.includes(Future.value(3), 1));
- log(array.includes(1, 1));
输出结果为:
true
true
false
find 方法
- Future.prototype.find(predicate[, thisArg])
该方法是 Array.prototype.find
的 promise
版本。它与 Array.prototype.find
的区别跟 Future.find
和 Array.find
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- function isPrime(element, index, array) {
- var start = 2;
- while (start <= Math.sqrt(element)) {
- if (element % start++ < 1) {
- return false;
- }
- }
- return element > 1;
- }
- var array1 = Future.value([4, Future.value(6), 8, Future.value(12)]);
- var array2 = Future.value([4, Future.value(5), 7, Future.value(12)]);
- log(array1.find(isPrime));
- log(array2.find(isPrime));
输出结果为:
undefined
5
findIndex 方法
- Future.prototype.findIndex(predicate[, thisArg])
该方法是 Array.prototype.findIndex
的 promise
版本。它与 Array.prototype.findIndex
的区别跟 Future.findIndex
和 Array.findIndex
的区别相同。
- var Future = hprose.Future;
- var log = Future.wrap(console.log, console);
- function isPrime(element, index, array) {
- var start = 2;
- while (start <= Math.sqrt(element)) {
- if (element % start++ < 1) {
- return false;
- }
- }
- return element > 1;
- }
- var array1 = Future.value([4, Future.value(6), 8, Future.value(12)]);
- var array2 = Future.value([4, Future.value(5), 7, Future.value(12)]);
- log(array1.findIndex(isPrime));
- log(array2.findIndex(isPrime));
输出结果为:
-1
1