如何使用Promise
在说Promise之前,不得不说一下JavaScript的嵌套的回调函数
在JavaScript语言中,无论是写浏览器端的各种事件处理回调、ajax回调,还是写Node.js上的业务逻辑,不得不面对的问题就是各种回调函数。回调函数少了还好,一旦多了起来而且必须讲究执行顺序的话,回调函数开始嵌套,那代码的恶心程度是相当不符合常人的线性思维的。
1 // 就像下面这样: 2 // 你不在乎下面这三个ajax的执行顺序还好 3 // 如果你在乎顺序呢? 4 $.get('url', function(){ 5 6 }, 'json'); 7 $.get('url1', function(){ 8 9 }, 'json'); 10 $.get('url2', function(){ 11 12 }, 'json'); 13 14 // 就像这样? 15 $.get('url', function(){ 16 $.get('url1', function(){ 17 $.get('url2', function(){ 18 19 }, 'json'); 20 }, 'json'); 21 }, 'json'); 22 23 24 // 下面是我最近写的一段Node.js的代码 25 // 其实这个嵌套也不算多 26 // 如果业务逻辑相当复杂起来呢? 27 // 嵌套20 30层? 28 var adminIndex = function(params, callback){ 29 storeAdmin.getApiTokens(function(err, tokens){ 30 if ( err ) { callback(err); return; } 31 storeAdmin.getApiServices(function(err, apiServices){ 32 if ( err ) { callback(err); return; } 33 storeAdmin.getSocketioServices(function(err, socketioServices){ 34 if ( err ) { callback(err); return; } 35 callback(0, { 36 status : true, 37 data : { 38 api_tokens : tokens, 39 api_services : apiServices, 40 socketio_services : socketioServices 41 } 42 }); 43 }); 44 }); 45 }); 46 };
说了这么多,到底什么是Promise呢?
其实,Promise就是一个类,而且这个类已经成为了ES6的标准,这个类目前在chrome32、Opera19、Firefox29以上的版本都已经支持了,要想在所有浏览器上都用上的话就看看es6-promise吧。
那Promise怎么用呢?
看一段很简单的代码,请注意阅读代码中的注释。
1 var val = 1; 2 3 // 我们假设step1, step2, step3都是ajax调用后端或者是 4 // 在Node.js上查询数据库的异步操作 5 // 每个步骤都有对应的失败和成功处理回调 6 // 需求是这样,step1、step2、step3必须按顺序执行 7 function step1(resolve, reject) { 8 console.log('步骤一:执行'); 9 if (val >= 1) { 10 resolve('Hello I am No.1'); 11 } else if (val === 0) { 12 reject(val); 13 } 14 } 15 16 function step2(resolve, reject) { 17 console.log('步骤二:执行'); 18 if (val === 1) { 19 resolve('Hello I am No.2'); 20 } else if (val === 0) { 21 reject(val); 22 } 23 } 24 25 function step3(resolve, reject) { 26 console.log('步骤三:执行'); 27 if (val === 1) { 28 resolve('Hello I am No.3'); 29 } else if (val === 0) { 30 reject(val); 31 } 32 } 33 34 new Promise(step1).then(function(val){ 35 console.info(val); 36 return new Promise(step2); 37 }).then(function(val){ 38 console.info(val); 39 return new Promise(step3); 40 }).then(function(val){ 41 console.info(val); 42 return val; 43 }).then(function(val){ 44 console.info(val); 45 return val; 46 }); 47 48 // 执行之后将会打印 49 步骤一:执行 50 Hello I am No.1 51 步骤二:执行 52 Hello I am No.2 53 步骤三:执行 54 Hello I am No.3 55 Hello I am No.3
Promise到底解决什么问题?
正如上面代码所示,笔者认为,Promise的意义就在于 then 链式调用 ,它避免了异步函数之间的层层嵌套,将原来异步函数的嵌套关系 转变为便于阅读和理解的 链式步骤关系 。
Promise的主要用法就是将各个异步操作封装成好多Promise,而一个Promise只处理一个异步逻辑。最后将各个Promise用链式调用写法串联,在这样处理下,如果异步逻辑之间前后关系很重的话,你也不需要层层嵌套,只需要把每个异步逻辑封装成Promise链式调用就可以了。
Promise常用的关键点
在Promise定义时,函数已经执行了
Promise构造函数只接受一个参数,即带有异步逻辑的函数。这个函数在 new Promise
时已经执行了。只不过在没有调用 then
之前不会 resolve 或 reject。
在then中的resolve方法中如何return?
在then方法中通常传递两个参数,一个 resolve
函数,一个 reject
函数。reject
暂时不讨论,就是出错的时候运行的函数罢了。resolve
函数必须返回一个值才能把链式调用进行下去,而且这个值返回什么是有很大讲究的。
-
resolve
返回一个新 Promise
返回一个新Promise之后再调用的then就是新Promise中的逻辑了。
-
resolve
返回一个值
返回一个值会传递到下一个then的resolve方法参数中。