• 【ES6】Generator+Promise异步编程


    一、概念

    首先我们要理解Generator和Promise的概念。

    Generator:意思是生成器,可以在函数内部通过yeild来控制语句的执行或暂停状态。

    *Foo(){
        yeild console.log('step1');
        yeild console.log('step2');
    }
    
    run(foo){
        var step = foo();
        while(!step.done){
            step.next();
        }
    }
    
    run(Foo);
    
    // step1
    // step2
    

    通过上面这个例子可以看到,使用*将Foo声明为Generator函数,然后再执行Foo的时候,不会执行到底,而是执行到第一句yeild就停下来。只有调用next()才会执行到下一步yeild。

    Promise:是ES6新增的一个对象,相当于一个容器,是用来专门处理异步处理的。

    function request = new Promise((resolve,reject) => {
        $.ajax({
            type: "GET",
            url: "/someajaxurl",
            contentType: "application/json",
            dataType: "json",
            success: function (data) {
                resolve(data);
            },
            error: function (xhr) {
                reject(xhr);
            }
        });
    }).then(data=>{
        // success  method
    }).catch(xhr=>{
        // error method
    });

    二、Generator和Promise的结合

    假设我们有个需求,需要调用两个接口,并且这两个接口不能同时启动异步调用,而是要先调接口1,在调接口2。

    那么在没有使用Generator的情况下是这么写的。

    // 使用promise异步调用数据
    request(url){
    	return new Promise((resolve,reject) => {
    		$.ajax({
    	        type: "GET",
    	        url: "/someajaxurl",
    	        contentType: "application/json",
    	        dataType: "json",
    	        success: function (data) {
    	            resolve(data);
    	        },
    	        error: function (xhr) {
    	            reject(xhr);
    	        }
    	    });
    	});
    }
    
    // 先调用接口1,再点用接口2
    gen(){
    	var nameList = [];
    	request('user/name1').then(data => { 
    		nameList.push(data) ;
    		request('user/name2').then(data => { 
    			nameList.push(data) 
    		});
    	});
    }
    
    gen();
    

    以上例子会发现最终会有一个长嵌套的回调函数。

    如果我们使用Generator的话,那么代码如下:

    // 使用promise异步调用数据
    request(url){
    	return new Promise((resolve,reject) => {
    		$.ajax({
    	        type: "GET",
    	        url: "/someajaxurl",
    	        contentType: "application/json",
    	        dataType: "json",
    	        success: function (data) {
    	            resolve(data);
    	        },
    	        error: function (xhr) {
    	            reject(xhr);
    	        }
    	    });
    	});
    }
    
    
    // 使用generator,将回调函数嵌套的写法改为同步写法
    *gen(){
    	var nameList = [];
    	yeild request('user/name1').then(data => { nameList.push(data) });
    	yeild request('user/name2').then(data => { nameList.push(data) });
    }
    
    // 执行generator的next方式
    (function(){
    	var step = gen();
    	while(!step.done){
    		step.next();
    	}
    });
    

    使用generator的写法,会发现省去一大堆的嵌套,代码变得直观很多。

    三、Async

    上面的例子,发现代码变得直观了,但是还需要另外写个方法去执行generator。这时候ES6中的新特性Async,还可以对代码做进一步的优化。

    // 使用async,效果和generator差不多,只不过将函数内部的yeild改为await.但是async自带执行器,不需要另外再写个方法去执行next.
    async gen(){
    	var nameList = [];
    	await request('user/name1').then(data => { nameList.push(data) });
    	await request('user/name2').then(data => { nameList.push(data) });
    }
    

      

  • 相关阅读:
    RAID中条带的概念
    关于几个与IO相关的重要概念
    分布式调度
    ajax
    choices参数
    1.Python实现字符串反转的几种方法
    django web框架
    CRM总结
    Python面试重点(web篇)
    day02-网编并发数据库
  • 原文地址:https://www.cnblogs.com/nonkicat/p/7372532.html
Copyright © 2020-2023  润新知