zoukankan      html  css  js  c++  java
  • Promise A 规范的一个简单的浏览器端实现

    简单的实现了一个promise 的规范,留着接下来模块使用。感觉还有很多能优化的地方,有时间看看源码,或者其他大神的代码

    主要是Then 函数。回调有点绕人。

      1 !(function(win) {
      2 
      3 
      4 
      5   function Task(resolver) {
      6     if (!resolver || (typeof resolver).toUpperCase() != 'FUNCTION') {
      7       throw 'task arg is function,and is must';
      8       return;
      9     }
     10 
     11 
     12     if (!(this instanceof Task)) return new Task(resolver);
     13 
     14     var self = this;
     15     //PENDING,FULFILLED,REJECTED
     16     self.statu = 'PENDING';
     17     self.callbackok = null;
     18     self.callbackreject = null;
     19 
     20     self.value = null;
     21     self.reason = null;
     22 
     23     function resolve(data) {
     24       self.statu = 'FULFILLED';
     25       self.value = data || {};
     26       self.callbackok && self.callbackok(self.value);
     27     }
     28 
     29     function reject(reason) {
     30       self.statu = 'REJECTED';
     31       self.reason = reason || {};
     32       self.callbackreject && self.callbackreject(self.reason);
     33     }
     34 
     35 
     36     resolver(resolve, reject);
     37 
     38   }
     39 
     40   
     41   Task.all = function(arr) {
     42 
     43     if (!(arr instanceof Array)) {
     44       throw 'arr must be Task Array';
     45       return;
     46     }
     47 
     48     return Task(function(resolve, reject) {
     49       var dataarr = {};
     50       var len = arr.length;
     51       for (var i = 0; i < len; i++) {
     52         (function(c) {
     53           console.log(arr[c]);
     54           arr[c].then(function(data) {
     55             dataarr[c] = data;
     56             len--;
     57             if (len == 0) {
     58               var data = new Array(len);
     59               for (var item in dataarr) {
     60                 data[item] = dataarr[item];
     61               }
     62               resolve(data);
     63             }
     64 
     65           }, function(error) {
     66             reject(error);
     67           })
     68         })(i)
     69       }
     70     })
     71   }
     72 
     73   //创建一个成功状态的Task对象
     74   Task.resolve = function(value) {
     75 
     76     return new Task(function(resolve) {
     77       resolve(value);
     78     })
     79   }
     80 
     81   Task.prototype.then = function(onFulfilled, onRejected) {
     82 
     83     var task = this;
     84 
     85     return Task(function(resolve, reject) {
     86 
     87       function callback(value) {
     88 
     89         var ret = (typeof onFulfilled).toUpperCase() == 'FUNCTION' && onFulfilled(value) || value;
     90 
     91         if (isThenable(ret)) {
     92           ret.then(function(value) {
     93             resolve(value);
     94           }, function(reason) {
     95             reject(reason);
     96           });
     97         } else {
     98           resolve(ret);
     99         }
    100       }
    101 
    102       function errorback(reason) {
    103         reason = (typeof onRejected).toUpperCase() == 'FUNCTION' && onRejected(reason) || reason;
    104         reject(reason);
    105       }
    106 
    107       if (task.statu === 'PENDING') {
    108         task.callbackok = callback;
    109         task.callbackreject = errorback;
    110       } else if (task.statu === 'FULFILLED') {
    111         callback(task.value);
    112       } else if (task.statu === 'REJECTED') {
    113         errorback(task.reason);
    114       }
    115 
    116     });
    117 
    118   }
    119 
    120   var isThenable = function(obj) {
    121     return obj && typeof obj['then'] == 'function';
    122   }
    123 
    124   window.Task = Task;
    125 
    126 })(window)
    View Code

    下面是几种调用

    串行

     1 var task = new Task(function(resolve, reject) {
     2     setTimeout(function() {
     3       resolve('aaaa');
     4     }, 100);
     5   })
     6   var task1 = function() {
     7     return new Task(function(resolve, reject) {
     8       setTimeout(function() {
     9         resolve('bbbb');
    10       }, 100);
    11     })
    12   }
    13   var task2 = function() {
    14     return new Task(function(resolve, reject) {
    15       setTimeout(function() {
    16         resolve('cccc');
    17       }, 100);
    18     })
    19   }
    20   var task3 = function() {
    21     return new Task(function(resolve, reject) {
    22       setTimeout(function() {
    23         reject('dddd');
    24       }, 100);
    25     })
    26   }
    27   task.then(task1).then(task2).then(task3).then(function(data) {
    28     console.log(data)
    29   }, function(error) {
    30       console.log(data)
    31   });
    View Code

    并行

     1  var task = new Task(function(resolve, reject) {
     2     setTimeout(function() {
     3       resolve('aaaa');
     4     }, 100);
     5   })
     6   var task2 = new Task(function(resolve, reject) {
     7     setTimeout(function() {
     8       resolve('aaaa');
     9     }, 100);
    10   })
    11   var task3 = new Task(function(resolve, reject) {
    12     setTimeout(function() {
    13       resolve('aaaa');
    14     }, 100);
    15   })
    16   var task4 = new Task(function(resolve, reject) {
    17     setTimeout(function() {
    18       resolve('aaaa');
    19     }, 100);
    20   })
    21   var task5 = new Task(function(resolve, reject) {
    22     setTimeout(function() {
    23       resolve('aaaa');
    24     }, 100);
    25   })
    26  //并行
    27  Task.all([task,task2,task3,task4,task5]).then(function(data){ console.log(data)})
    View Code

    创建一个一开始就是 释放状态的 task

    Task.resolve('data').then(function(data){
             console.log(data);
         })
  • 相关阅读:
    Electron+Vue开发跨平台桌面应用
    html2canvas生成图片
    将某个DIV内容保存成图片,使用HTML2CANVAS截图方法(高清图并解决图片跨域问题)
    css3实现动画效果完整代码demo
    Vue + element从零打造一个H5页面可视化编辑器——pl-drag-template
    Vue.Draggable学习总结
    3d学习网
    vue router 报错: Uncaught (in promise) NavigationDuplicated {_name:""NavigationDuplicated"... 的解决方法
    网页适配 iPhoneX,就是这么简单
    关于for循环
  • 原文地址:https://www.cnblogs.com/btgyoyo/p/5857919.html
Copyright © 2011-2022 走看看