×

JavaScript Promise是个什么鬼玩意?

作者:jquery2018.04.25来源:Web前端之家浏览:23860评论:0
关键词:Promisejs

刚开始接触JavaScript Promise,一脸懵逼,啥玩意,了解学习后,一脸茫然,哈哈!来学下吧~

什么是Promise?

在说Promise之前,不得不说一下JavaScript的嵌套的回调函数

在JavaScript语言中,无论是写浏览器端的各种事件处理回调、ajax回调,还是写Node.js上的业务逻辑,不得不面对的问题就是各种回调函数。回调函数少了还好,一旦多了起来而且必须讲究执行顺序的话,回调函数开始嵌套,那代码的恶心程度是相当不符合常人的线性思维的。

说到这里,我真有点想去了解一下响马老师的fibjs,我没有接触过它,但它的编程方式就是线性的,更加符合常人思维。我个人认为Promise就是为了把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方法参数中。

您的支持是我们创作的动力!
温馨提示:本文作者系 ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://jiangweishan.com/article/Promise1223230rfweopfi.html

网友评论文明上网理性发言 已有0人参与

发表评论: