/**
* Promise 章节代码片段
*/
// :1 异步获取x,y,当两个都有值的时候再做运算
function add(getX, getY, cb){
var x, y;
getX(function(xVal){
x = xVal;
if(y != undefined){
cb(x+y);
}
});
getY(function(yVal) {
y = yVal;
if(x != undefined){
cb(x+y);
}
});
}
add(
fetchX,
fetchY,
function(sum){
console.log(sum);
}
)
// :2
function add(xPromise, yPromise) {
// Promise.all()接受一个promise数组并返回一个新的promise
// 这个新promise等待数组中所有promise完成
return Promise.all( [xPromise, yPromise] )
.then(function(values){
return values[0] + values[1];
});
}
add( fetchX(), fetchY())
.then(function(sum){
console.log(sum);
});
// :3 then()实际上可以接受两个函数,第一个用于完成,第二个用于拒绝
add( fetchX(), fetchY())
.then(
function(sum){
console.log(sum);
},
function(err){
console.log(err);
}
)
// :4 Promise的运作方式,C无法打断或抢占B,输出:A B c
p.then(
function(){
p.then(
function(){
console.log('C');
}
);
console.log('A')
}
);
p.then(
function(){
console.log('B')
}
);
// :5 Promise 调度技巧 输出:A B
var p3 = new Promise(function(resolve, reject){
resolve('B');
});
var p1 = new Promise(function(resolve, reject){
resolve(p3);
});
var p2 = new Promise(function(resolve, reject){
resolve('A');
});
p1.then(function(v){
console.log(v);
});
p2.then(function(v){
console.log(v);
});
// :6
function timeoutPromise(delay) {
return new Promise(function(resolve, reject){
setTimeout(() => {
reject( "Timeout" )
}, delay);
});
}
Promise.race([
foo(),
timeoutPromise( 3000 )
])
then(function(){
// foo(..) 及时完成
},function(err){
// 被拒绝,输出错误信息
});
// :7
var p = new Promise(
function(resolve,reject){
foo.bar();
resolve(42); //永远执行不到这里
}
);
p.then(
function(){
// 永远不会到达这里
},
function(err){
// err 将会是一个来自foo.bar()这一行的TypeError的异常对象
}
);
// :8
var p1 = new Promise(function(resolve, reject){
resolve(42);
});
var p2 = Promise.resolve(42);
// :9
var p1 = Promise.resolve(42);
var p2 = Promise.resolve(p1);
p1 === p2; // true
// :10
v
ar p = {
then: function(cb){
cb(42);
}
}
// 这可以工作,但只是因为幸运而已
p
.then(
function fulfilled(val){
console.log(42);
},
function rejected(err){
// never
}
);
// :11
// don't
foo(42)
.then(function(v){
console.log(v);
});
// right
Promise.resolve(foo(42))
then(function(v){
console.log(v);
});
// :12 链式流
var p = Promise.resolve(21);
var p2 = p.then(function(v){
console.log('v');
return v * 2;
});
p2.then(function(v){
console.log(v);
});
// :13
var p = Promise.resolve(21);
p.then(function(v){
return v * 2;
})
.then(function(v){
console.log(v); // 42
});
// :14
var p = Promise.resolve(21);
p.then(function(v){
console.log(v); // 21
return new Promise(function(resolve,reject){
resolve(v*2);
});
})
.then(function(v){
console.log(v); // 42
});
// :15
var p = Promise.resolve(21);
p.then(function(v){
console.log(v);
return new Promise(function(resolve, reject){
setTimeout(() => {
resolve(v * 2);
}, 100);
});
})
.then(v => {
console.log(v); // 42
});
// :16
function delay(time) {
return new Promise(function(resolve, reject){
setTimeout( resolve, time);
});
}
delay(100)
.then(function(){
console.log('step 2 after 100ms')
return delay(200);
})
.then(function(){
console.log('step 3 after another 200ms');
})
.then(function(){
console.log(' step 4 ');
return delay(50);
})
.then(function(){
console.log('step 5 after another 50ms')
});
// :17
function request(url){
return new Promise(function(resolve, reject){
ajax(url, resolve);
});
}
request('http://request.url')
.then(function(response1){
return request('http://another.request.url');
})
.then(function(response2){
console.log(response2);
});
// :18 处理错误
request('http://xxx')
.then(function(resp1){
foo.bar(); // undefined, error!
return request('http://xxx2');
})
.then(function(resp2){
// never
},function(err){
console.log(err);
return 42;
})
then(function(msg){
console.log(msg); // 42
});
/**
* 总结:链式流程控制可行的Promise固有特性:
* 1、调用Promise的then()会自动创建一个新的Promise从调用返回
* 2、在完成或拒绝处理函数内部,如果返回一个值或抛出一个异常,新返回的Promise就相应地决议。
* 3、如果完成或拒绝处理函数返回一个Promise,它将会被展开,不管它的决议值是什么,都会成为当前then返回的链接Promise的决议值。
* 更好的模式:生成器
* */
// :19
var rejectedPr = new Promise(function(resolve, reject){
resolve(Promise.reject("Oops"));
});
rejectedPr.then(function(){
// never
},function(err){
console.log(err); // Oops
});
// :20 , try…catch…无法跨异步操作
function foo(){
setTimeout(function(){
bar.baz();
}, 1000);
}
try {
foo();
//后面从bar.baz();抛出全局错误
}
catch (err) {
// never
}
// :21 error first 风格
function foo(cb){
setTimeout(function(){
try {
var x = baz.bar();
cb(null, x)
}
catch(err){
cb(err)
}
},100);
}
foo(function(err,val){
if(err){
console.log(err);
}else{
console.log(val);
}
})
// :22
var p = Promise.resolve('Oops');
p.then(
function fulfilled(){
//never
},
function rejected(err) {
console.log(err)
}
);
// :23
var p = Promise.resolve(42);
p.then(
function fulfilled(msg){
// 数字没有string函数,所以会抛出异常
console.log(msg.toLowerCase());
},
function rejected(err){
//never
}
)
// :24 同时请求
var p1 = request('http://url.com');
var p2 = request('http://url2.com');
Promise.all([p1,p2])
.then(function(msgs){
return request('http://url3.com');
})
.then(function(msg){
console.log(msg);
});
// :25 竟态
var p1 = request('http://url.com');
var p2 = request('http://url2.com');
Promise.race([p1,p2])
.then(function(msg){
return request('http://url3.com');
})
.then(function(msg){
console.log(msg);
});
// :26
Promise.race(
foo(),
timeoutPromise(3000)
)
then(
function () {
// foo() 按时完成
},
function(err){
// foo()没有按时完成
// 查看错误原因
}
)
// :27
if(!Promise.map){
Promise.map = function(vals, cb){
return Promise.all(
vals.map(function(val){
return new Promise(function(resolve){
cb(val, resolve);
});
})
)
}
}
// :28
var p1 = Promise.resolve(21);
var p2 = Promise.resolve(42);
var p3 = Promise.reject('Oops');
Promise.map([p1,p2,p3], function(pr, done){
Promise.resolve(pr)
.then(
function(v){
done(v*2);
},
done
)
})
.then(function(vals){
console.log(vals);
});
// :29
function getY(x) {
return new Promise(function(resolve, reject) {
setTimeout(function(){
resolve((3*x) - 1);
},100);
});
}
function foo(bar, baz) {
var x = bar * baz;
// 返回2个promise
return [
Promise.resolve(),
getY(x)
];
}
Promise.all(foo(10,20))
.then(
function(msgs){
var x = msgs[0];
var y = msgs[1];
console.log(x,y);
}
);
// :30 解构-1
Promise.all(foo(10, 20))
.then(
function (msgs) {
var [x,y] = msgs;
console.log(x, y);
}
);
// :31 解构-2
Promise.all(foo(10, 20))
.then(
function ([x,y]) {
console.log(x, y);
}
);
// :32 promisory
if(!Promise.wrap){
Promise.wrap = function(fn){
return function(){
var args = [].slice.call(arguments);
return new Promise(function(resolve, reject){
fn.apply(
null,
args.concat(function(err,v){
if(err){
reject(err);
}else{
resolve(v);
}
})
)
})
}
}
}
var request = Promise.wrap(ajax);
request('http://some.url.1')
.then(function(){
});