多个异步请求顺序执行的几种方式 (学习笔记)

4,703 阅读4分钟

仅仅作为工作之余的一点学习整理,在实际业务开发场景,经常需要用到请求顺序执行的情况,比如界面回显的一些多级联动,稍微记录一下相关方式

1.简单粗暴(直接调用)



function setp1() {    
    setTimeout(() => {        
        console.log('执行1')        
        setp2('1传递的参数')    
    }, 2000);
}
function setp2(data) {    
    setTimeout(() => {        
        console.log('执行2', data)        
        setp3('2传递的参数')    
    }, 2000);
}
function setp3(data) {    
    setTimeout(() => {        
        console.log('执行3', data)    
    }, 2000);
}
setp1();

              

执行结果勒,自然是依次执行,这种方式简单粗暴,但是代码量一旦增多,过段时间的可读性很差,要是代码没在一块,还得不停的搜索,执行结果如下


2.Promise

关于这个Promise,个人查看了一些文档和博客,写了一个简化版的只有成功回调的MyPromise,调用是一样的。

贴下代码,一些个人理解


class MyPromise {
    constructor(func) {
        this.handles = {
            resolves: '',
            rejects: ''
        };
        this.statuInfo = {            
                resolves: 0
        };        
        func(this._revole.bind(this), this._reject.bind(this));
    }
    //promise里面的手动触发 一般是等到异步结果执行完毕之后触发,传递参数到下一个promise或者是function    
//执行的是promise实例对象 then里面的函数,successFuc或者是errorFuc
    _revole(value) {        
        this.statuInfo.resolves = 1;        
        this._value = value;
        if (this.handles.resolves) {            //对象在实例化的时候,已经储存了then里面的function并进行转换
            this.handles.resolves(value);
            delete this.handles.resolves;
        }    
    }
    _reject(value) {        
    }    
    then(onSuccess, onError) {
        const { statuInfo, _value } = this;
        return new MyPromise((resolve, reject) => {
            const success = (value) => {
                if (typeof onSuccess == 'function') {
                    //执行当前then函数                    
                    const res = onSuccess(value);
                    if (res instanceof MyPromise) {
                        // resolve,reject其实是返回出去的promise对象上用来触发回调方法,现在注册到res对象上,                        // 相当于我们在res的函数体里面,调用resolve的时候,
                        // 其实就是调用返回出去的promise对象的resolve,执行的自然是返回出去的promise绑定的then函数里面的方法了,达到链式调用的效果                        
                        res.then(resolve, reject);
                    } else {
                        //then里传递的参数为普通函数,没有再返回promise对象, 是否有下一个then函数,需要执行                        //这个过程是同步的,立马执行 所以then函数体里面如果是需要异步执行等待,则需要返回一个promise对象                        
                        resolve(res);
                    }
                } else {
                    //这种情况是then没有传递函数,也就没有需要回调的函数 其实是没有意义的                    
                    resolve(value);
                }            
            }
            if (statuInfo.resolves == 0) {

                this.handles.resolves = success
            } else {
                success(_value)            
            }
        })
        // return this;    
    }
}

凭感觉整理的大概的执行流程图,一些解释就放在图里了


promise的调用方式

 

function step1() {
    return new MyPromise(function (resolve, reject) {
        console.log('执行1')
        setTimeout(() => {
            console.log('1请求结束')
            resolve('1传递的参数')
        }, 4000);
    });
}
function step2(data) {
    return new MyPromise(function (resolve, reject) {
        console.log('执行2 ,接收的参数', data)
        setTimeout(() => {
            resolve('2传递的参数')
        }, 4000);
    });
}
function step3(data) {
    return new MyPromise(function (resolve, reject) {
        console.log('执行3 ,接收的参数', data)
        setTimeout(() => {
            resolve('3传递的参数')
        }, 4000);
    });
}
step1().then(step2).then(step3).then(res => {
    console.log('最后', res)//3传递的参数
});

执行结果如下


3.生成器(Generators)

生成器( generator)是能返回一个迭代器的函数。 生成器函数也是一种函数,最直观的表现就是比普通的function多了个星号*,在其函数体内可以使用yield关键字,函数会在每个yield后暂停,等待,直到这个生成的对象,调用下一个next(),每调用一次next 会往下执行一次yieId,然后暂停

 

function* main() {
    var result = yield step1("执行开始");
    var data2 = yield step2(result);
    var data3 = yield step3(data2);
    console.log('执行结束', data3);
    //do 别的ajax请求;
}

function step1(msg) {
    setTimeout(() => {
        console.log('第一个请求 compile', msg),
            it.next('第一个请求 result');
    }, 2000)
}
function step2(msg) {
    setTimeout(() => {
        console.log('第二个请求 compile', msg),
            it.next('第二个请求 result');
    }, 2000)
}
function step3(msg) {
    setTimeout(() => {
        console.log('第三个请求 compile', msg),
            it.next('第三个请求 result');
    }, 2000)
}

var it = main();
it.next();
console.log("执行到这儿啦");

当你调用一个generator时,它将返回一个迭代器对象。这个迭代器对象拥有一个叫做next的方法来帮助你重启generator函数并得到下一个值。next方法不仅返回值,

执行结果


总结

以上就是  感觉就是用的较多的一些方式,只是自己在看了一些资料之后自己的一些随笔记录(手动滑稽)