zoukankan      html  css  js  c++  java
  • JavaScript实现timeoutify、asyncify和promiseify

    三个在JavaScript异步编程中常用的ployfill工具:

     1 function timeoutify(f,t){
     2     //作用:对异步函数做超时检测,当异步函数在指定的时间内完成时才让它调用传入的回调
     3     let id=setTimeout(()=>{
     4         id=undefined;
     5     },t);
     6     return function(){
     7         if (id){
     8             //id还存在说明没有超时
     9             clearTimeout(id);
    10             f.apply(this,arguments);
    11         }else{
    12             //id是undefined说明超时了
    13             f(Error(`Refuse to execute the callback beacuse of Timeout.`));
    14         }
    15     };
    16 }
    17 
    18 function asyncify(f){
    19     //作用:避免出现Zalgo竞态条件,使异步函数对回调的调用始终是异步调用
    20     let id,origin_f;
    21     id=setTimeout(()=>{ //使用hack=setTimeout(0)检测回调是否被异步调用
    22         id=undefined;
    23         if (f){ //能进入这个if语句,说明回调被同步调用
    24             f(); //使用hack-setTimeout(0)对这个回调强制进行异步调用
    25         }
    26     },0);
    27     origin_f=f;
    28     f=null;
    29     return function _result(){
    30         //原理:当调用asyncify时,立刻进行setTimeout(0)倒计时,只有是同步调用,才会导致触发_result时id存在值
    31         if (id){
    32             //id还存在说明出现了Zalgo,即这个回调被同步调用了,要避免这种情况
    33             f=origin_f.bind.apply(origin_f,[this].concat([].slice.call(arguments))); //arguments作为科里化参数
    34         }else{
    35             //已经是异步了,正常执行
    36             origin_f.apply(this,arguments);
    37         }
    38     };
    39 }
    40 
    41 function promiseify(f){
    42     //作用:将一个传统的异步函数promise化
    43     /*
    44     传入的异步函数要求:
    45     1.最后一个参数是回调函数
    46     2.这个回调函数使用error-first风格
    47     promiseify返回一个新函数,新函数的参数列表移除了原函数参数列表的回调函数,其他参数相同
    48     */
    49     return function(){
    50         return new Promise((ok,fail)=>{
    51             let args=[].slice.call(arguments);
    52             args.push(function(err,data){ //传入用于断定promise决议结果的函数作为原函数的回调函数
    53                 if(err)
    54                     fail(err); //ok和fail函数本身不返回值(即返回undefined)
    55                 else
    56                     ok(data);
    57                 
    58             });
    59             f.apply(this,args);
    60         });
    61     };
    62 }
  • 相关阅读:
    超微主板不识别M2-解决方案
    Centos7安装zookpeer
    PowerBI主题制作
    [python错误]UnicodeDecodeError: 'gbk' codec can't decode byte...
    使用Python批量合并PDF文件(带书签功能)
    Oracle使用超大SQL脚本文件恢复数据问题记录
    Linux Mint 18.2安装后需要进行的设置
    Excel使用SUMIF函数注意事项
    CSV文件分割与列异常处理的python脚本
    小程序例子
  • 原文地址:https://www.cnblogs.com/ryzz/p/13264798.html
Copyright © 2011-2022 走看看