异步函数顺序执行的实现(上)

本文介绍了一种确保异步任务按指定顺序执行的方法。通过构建任务链表,并修改每个任务函数,使其执行完毕后自动调用下一个任务。针对异步函数如setTimeout进行了重写,以确保整个流程的有序性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天在研究实现一个类似Promise思想的库,也不完全一样,主要目标是保证异步事件的执行顺序。

比如有四个异步事件A,B,C,D
需要这样一个执行顺序 A => B => C => D

想了好几种方案。
其中有一种是先建立一个任务链表,执行时修改每个事件的函数内容。

假设现在任务链表顺序已经建立, A => B => C => D。

taskList[function A,function B,function C,function D]

并且四个函数大概是这样:

function A(){
alert('第一个函数');
}

function B(){
alert('第二个函数');
}

//C函数是个异步函数
function C(){
    setTimeout(function(){
        alert('第三个函数,延迟3秒执行');
    },3000)
}

function D(){
alert('第四个函数');
}

还有一个修改函数的函数inject,这个函数执行时可以修改前面四个函数的内容。


function inject(fn){
//对每一个传入的fn进行修改,然后才能执行
}

首先,这个inject函数这样写:
1.先加载fn参数的内容:

function inject(fn){
    var source = fn.toString();
}

得到source的值就是函数A的定义:

function A(){
alert('第一个函数');
}

2.给source增加一句执行链表中下一个函数的代码。
这里我想了个办法,先去掉source中function (){},留下的就是函数体的内容。

function inject(fn){
    var source = fn.toString();
    var startPos = source.indexOf('{') + 2,
        endPos = source.lastIndexOf('}') -1;
        //{ 和 }的位置
        //+2是加上{本身和换行的位置
        //-1是减去换行的位置
        
    source = source.substring(StartPos,endPos);
    //截取出来函数体 alert('第一个函数');
    
    source += "taskList.shift();taskList[0]();"; 
    //写入自定义代码到函数体,链表taskList将首项shift掉,这样把第二个函数移到了第一位,然后再执行。
    
    //使用eval执行修改后的函数体
    try{
      eval(source);
    }
    catch(err){
      alert(err);
    }
}

这样,执行完inject(A),会自动执行B函数。

同理,如果A,B,C,D四个函数都是同步的,那么只需要inject这一个函数就可以让他们按顺序执行。

来考虑异步的C函数,我们依葫芦画瓢,用inject函数的思想,来重写一下C函数中调用的setTimeout方法。

var _setTimeout = setTimeout,
    setTimeout = function(fn,time){
     var source = fn.toString(),
      startPos = source.indexOf('{') + 2,
      endPos = source.lastIndexOf('}') -1;
      source = source.substring(startPos,endPos) + "taskList.shift();taskList[0]();"; 
     
      try{
        _setTimeout(function(){eval(source)},time);
      }
      catch(err){
        alert(err);
      }  
        
    }

如此,把调用下一个函数的方法放在定时器内,就完成了对setTimeout的重写。

我们把所有的代码放在一起测试一下(我使用的是console.log输出,按F12查看,刷新一下。)
https://html50.github.io/chain.js/test1.html

可以看出,A,B,C,D依次输出了。
对于其他异步函数的执行,方法是类似的:重写。

下一节,我将把这些函数使用构造函数的方法,包裹起来,加入ajax的方法。

转载于:https://www.cnblogs.com/2bit/p/6613222.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值