ECMAScript 6.0基础入门教程(二)-Promise、generator

ECMAScript 6.0基础入门教程(二)

8、Promise

Promise——承诺

8.1 异步

  1. 操作之间没有关系
  2. 同时进行多个操作
  3. 回调写法代码复杂(回调地狱)

下面是异步操作代码,如果想要同时读取不同模块的数据,就要写成回调方式。

ajax('/top', function (top_data){
    //top读取成功
    ajax('/left', function (left_data){
        //left读取成功
        ajax('/right', function (right_data){
            //right读取成功
            ajax('/bottom', function (bottom_data){
                //bottom读取成功
            },function (){
                console.log('bottom读取失败');
            })
        },function (){
            console.log('right读取失败');
        })
    },function (){
        console.log('left读取失败');
    })
},function (){
    console.log('top读取失败');
})

8.2 同步

  1. 同时只能做一件事
  2. 代码排队执行
  3. 代码简单,方便维护

下面是同步代码,不同模块分别调用,代码简洁:

let top_data = ajax_async('/top');
let left_data = ajax_async('/left');
let right_data = ajax_async('/right');
let bottom_data = ajax_async('/bottom');

8.3 Promise使用用法

  • Promise可以消除异步操作,用同步的方式来书写异步代码
let p = new Promise(resolve,reject){
    $.ajax({
        url: 'a.txt',
        dataType: 'json',
        success(data){
            resolve(data);   //resolve成功
        },
        error(err){
            reject(err);     //reject失败
        }
    })
}
p.then(function(data){
    console.log('成功'+data);
}, function (err){
    console.log('失败'+err);
});

8.4 Promise.all()的使用方法

  • 我们用Promise创建了两个异步操作,使用Promise.all()来同时执行这两个操作,如果全部成功了就成功了,如果其中有一个失败了就失败了,等同于&&的关系。

  • 除了Promise.all(),还有Promise.race() 方法,这两个方法的使用方法一样,不一样的是Promise.race()只执行成功的,忽略失败的,等同于||的关系。

let p1 = new Promise(resolve,reject){
    $.ajax({
        url: 'arr.txt',
        dataType: 'json',
        success(data){
            resolve(data);
        },
        error(err){
            reject(err);
        }
    })
}
let p2 = new Promise(resolve,reject){
    $.ajax({
        url: 'json.txt',
        dataType: 'json',
        success(data){
            resolve(data);
        },
        error(err){
            reject(err);
        }
    })
}
Promise.all([
    p1, p2
    ]).then(
    function (data){
        let [res1,res2] = data;  //解构赋值
        console.log('全部成功了');
        console.log(res1);
        console.log(res2);
    }, function (){
        console.log('有一个失败了就是失败了');
    }
)

8.5 封装Promise

function createPromise(url){
    return new Promise(resolve,reject){
        $.ajax({
            url,                //key和value一样,留一个就行
            dataType: 'json',
            success(data){
                resolve(data);
            },
            error(err){
                reject(err);
            }
        })
    }
}
Promise.all([
        createPromise('arr.txt');
        createPromise('json.txt');
    ]).then(
    function (data){
        let [res1,res2] = data;  //解构赋值
        console.log('全部成功了');
        console.log(res1);
        console.log(res2);
    }, function (){
        console.log('有一个失败了就是失败了');
    }
)

8.6 jquery的Promise使用

高版本jquery自带Promise支持
先在页面引入最新版本的jQuery

$.ajax({url: 'arr.txt, dataType: 'json'});

Promise.all([
        $.ajax({url: 'arr.txt, dataType: 'json'});
        $.ajax({url: 'json.txt, dataType: 'json'});
    ]).then(results => {
        let [res1,res2] = results;  //解构赋值
        console.log('全部成功了');
        console.log(res1);
        console.log(res2);
    }, err => {
        console.log('有一个失败了就是失败了');
    }
)

9、generator

generator生成器

  • 普通函数:执行完才结束
  • generator函数:中间能暂停

9.1 generator函数的写法

  • 在function和函数名中加上*,可以跟在function后面,也可以在function和函数名中间,也可以在函数名前面。

  • generator不能写成箭头函数方式。

function* show(){}
function * show(){}
function *show(){}
  • yield
```
function *show(){
    console.log(1);
    yield;  //放弃执行
    console.log(2);
}
let genObj = show();    //创建一个generator对象
genObj.next();          //1,调用next()执行一次
  • generator原理是生成了一堆小函数:
genObj.next();  //show_1(){console.log(1)};
genObj.next();  //show_2(){console.log(2)};

9.2 yield传参、返回

  • yield传参
function *show(){
    let a = yield;  //放弃执行
    console.log(a);   //5
}
let gen = show();
gen.next(10);  //第一个next无法传参,第一个传参要写在generator函数参数里
gen.next(5);
  • 根据上面代码我们可以知道generator无法接收到第一个next方法的参数,我们可以将第一个参数直接传入到generator函数参数里:
function *show(num){
    console.log(num);  //10
    let a = yield;     //放弃执行
    console.log(a);    //5
}
let gen = show(10); //第一个next()传参要写在generator函数参数里
gen.next();  
gen.next(5);
  • generator原理是生成了一堆小函数:
genObj.next();  //show_1(){console.log(1)};
genObj.next();  //show_2(){console.log(2)};
  • yield返回

yield返回值有两个参数:
1. value就是generator函数执行到当前yield语句之后得到的值
2. done表示函数是否执行完成,true代表函数全部执行完成,flase代表函数暂停状态未执行完成

 function *show(){
    console.log(1);
    let a = yield;  //放弃执行
    console.log(2);
    return 3;
}
let gen = show();
let res1 = gen.next();
console.log(res1);  //{value:1,done:false}
let res2 = gen.next();
console.log(res2);  //{value:undefined,done:true}
console.log(res2);  //{value:3,done:true}   最后的返回值要通过return返回

9.3 generator的用途

  • 当Promise有逻辑执行的时候会比异步回调写法还麻烦,所以我们在工作中遇到异步需要逻辑判断的时候可以使用generator来写。
  • generator在有逻辑判断情况下写起来很简单
function *main(){
    let data1 = yield $.ajax({url: '', dataType: 'json'});

    if(data1.data == true) {
        let data2 = yield $.ajax({url: '', dataType: 'json'});
    } else {
        let data3 = yield $.ajax({url: '', dataType: 'json'});
    }
}
let gen = main();

你可能感兴趣的:(ECMAScript,6.0,es6,promise,generator,javascript)