六月第三周(6.22-6.27)的安排
promise用法1
promise用法2
promise手写
用法 promise状态不可逆性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var p1 = new Promise (function (resolve, reject ) { resolve("success1" ); resolve("success2" ); }); var p2 = new Promise (function (resolve, reject ) { resolve("success" ); reject("reject" ); }); p1.then(function (value ) { console .log(value); }); p2.then(function (value ) { console .log(value); }); success1 success
promise中的异常处理
first scene1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var p1 = new Promise ( function (resolve,reject ) { foo.bar(); resolve( 1 ); }); p1.then( function (value ) { console .log('p1 then value: ' + value); }, function (err ) { console .log('p1 then err: ' + err); } ).then( function (value ) { console .log('p1 then then value: ' +value); }, function (err ) { console .log('p1 then then err: ' + err); } ); p1 then err: ReferenceError foo is not defined p1 then then err: undefined
second scene1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 var p2 = new Promise (function (resolve,reject ) { resolve( 2 ); }); p2.then( function (value ) { console .log('p2 then value: ' + value); foo.bar(); }, function (err ) { console .log('p2 then err: ' + err); } ).then( function (value ) { console .log('p2 then then value: ' + value); }, function (err ) { console .log('p2 then then err: ' + err); return Promise .resolve('resolve' ); } ).then( function (value ) { console .log('p2 then then then value: ' + value); }, function (err ) { console .log('p2 then then then err: ' + err); } ); p2 then value: 2 p2 then then err: ReferenceError foo is not defined p2 then then then value: resolve
知识点
Promise对象的then方法返回一个新的Promise对象,因此可以通过链式调用then方法。
then方法接受两个参数,第一个是promise成功的回调,一个是失败的回调,两个函数只能一个被调用
promise.resolve() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 var p1 = Promise .resolve( 1 );var p2 = Promise .resolve( p1 );var p3 = new Promise (function (resolve, reject ) { resolve(1 ); }); var p4 = new Promise (function (resolve, reject ) { resolve(p1); }); console .log(p1 === p2); console .log(p1 === p3);console .log(p1 === p4);console .log(p3 === p4);p4.then(function (value ) { console .log('p4=' + value); }); p2.then(function (value ) { console .log('p2=' + value); }) p1.then(function (value ) { console .log('p1=' + value); }) true false false false p2=1 p1=1 p4=1
Promise.resolve()阔以接受一个普通值或者一个Promise对象作为参数 当参数是普通值的时候,返回一个resolved状态的promise对象 当参数是Promise对象时,直接返回这个promise对象,所以p1 === p2
链式调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 var p = new Promise (function (resolve, reject ) { resolve(1 ); }); p.then(function (value ) { console .log(value); return value*2 ; }).then(function (value ) { console .log(value); }).then(function (value ) { console .log(value); return Promise .resolve('resolve' ); }).then(function (value ) { console .log(value); return Promise .reject('reject' ); }).then(function (value ) { console .log('resolve: ' + value); }, function (err ) { console .log('reject: ' + err); }) 1 2 undefined resolve reject: reject
then两个参数的返回值是以下三种情况的一种
return 一个同步值或者undefined(没有返回一个值时默认是undefined),then 方法会返回一个resolved状态的promise对象,Promise对象的值就是这个返回值
return 另一个Promise,then会根据这个Promise的状态和值创建一个新的Promise对象返回
throw 一个同步异常 then方法返回一个rejected状态的promise,值是该异常
resolve vs reject 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 var p1 = new Promise (function (resolve, reject ) { resolve(Promise .resolve('resolve' )); }); var p2 = new Promise (function (resolve, reject ) { resolve(Promise .reject('reject' )); }); var p3 = new Promise (function (resolve, reject ) { reject(Promise .resolve('resolve' )); }); p1.then( function fulfilled (value ) { console .log('fulfilled: ' + value); }, function rejected (err ) { console .log('rejected: ' + err); } ); p2.then( function fulfilled (value ) { console .log('fulfilled: ' + value); }, function rejected (err ) { console .log('rejected: ' + err); } ); p3.then( function fulfilled (value ) { console .log('fulfilled: ' + value); }, function rejected (err ) { console .log('rejected: ' + err); } ); rejected: [object Promise ] fulfilled: resolve rejected: resolve
Promise回调函数中的第一个参数resolve,会对Promise执行”拆箱”动作。即当resolve的参数是一个Promise对象时,resolve会”拆箱”获取这个Promise对象的状态和值,但这个过程是异步的。p1”拆箱”后,获取到Promise对象的状态是resolved,因此fulfilled回调被执行;
p2”拆箱”后,获取到Promise对象的状态是rejected,因此rejected回调被执行。
但Promise回调函数中的第二个参数reject不具备”拆箱“的能力,reject的参数会直接传递给then方法中的rejected回调。因此,即使p3 reject接收了一个resolved状态的Promise,then方法中被调用的依然是rejected,并且参数就是reject接收到的Promise对象。
拆箱是异步操作,所以不具备拆箱的3执行的是同步操作
扩展—— try catch 问: 用一句话描述js异常是否能被try catch到 答: 能捕捉到的异常必须是线程执行已经进入try catch但try catch未执行完成的时候抛出来的
红绿灯问题 Qs: 题目:红灯三秒亮一次,绿灯一秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?(用 Promise 实现)
1 2 3 4 5 6 7 8 9 function red ( ) { console .log('red' ); } function green ( ) { console .log('green' ); } function yellow ( ) { console .log('yellow' ); }
利用then和递归实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 function red ( ) { console .log('red' ); } function green ( ) { console .log('green' ); } function yellow ( ) { console .log('yellow' ); } var light = function (timmer, cb ) { return new Promise (function (resolve, reject ) { setTimeout(function ( ) { cb(); resolve(); }, timmer); }); }; var step = function ( ) { Promise .resolve().then(function ( ) { return light(3000 , red); }).then(function ( ) { return light(2000 , green); }).then(function ( ) { return light(1000 , yellow); }).then(function ( ) { step(); }); var p4 = new Promise (function (resolve, reject ) { resolve('i am cpp' ) }) p4.then(function (val ) { console .log(val) return light(3000 , red); }).then(function ( ) { return light(2000 , green); }).then(function ( ) { return light(1000 , yellow); }) } step();
参考链接