开课吧前端1期.阶段2:ES6详解-4 Promise generator-认识生成器函数 generator-yield

发布时间 2023-09-10 11:13:35作者: 兔兔福

10、Promise

  • Promise -- 承诺
    • 异步: 操作之间没啥关系,同时进行多个操作
    • 同步: 同时只能做一件事
  • 优缺点
    • 异步:代码更复杂
    • 同步:代码简单  

 

//比如我要请求4个数据,真正生产还要判断,没法看了,缩进
//异步:特别麻烦
ajax('/banners',function(banners)){
    ajax('/hotItems',function(hotItems){         
     ajax('/slides',function(slides){
     ajax('/banners',function(banners){
     
     },function(){alert('读取失败')})
     },function(){alert('读取失败')})
     },function(){alert('读取失败')})
    },function(){alert('读取失败')})


//同步
let banners=ajax_async('/banners')
let hotItems=ajax_async('/hotItems')
let slides=ajax_async('/slides')
let banners=ajax_async('/banners')


Promise -- 消除异步操作
*用同步一样的方式,来书写异步代码
    
//Promise到底怎么用
let p = new Promise(function(resolve,reject){
    //异步代码
    //resolve() --成功了
    //reject() --失败了
    $.ajsx({
        url:'arr.txt',
        dataType:'json',
        success(arr){resolve(arr)},
        error(err){reject(err)}
    })
})
//翻译then然后呢,有结果了才调用函数
p.then(function(arr){
    alert('成功'+arr)
},function(err){
    alert('失败'+err)
}); 

调用2个异步

只有当2个promise成功,才算成功

 

let p1 = new Promise(function(resolve,reject){
    //异步代码
    //resolve --成功了
    //reject --失败了
    $.ajsx({
        url:'arr.txt',
        dataType:'json',
        success(arr){resolve(arr)},
        error(err){reject(err)}
    })
})

let p2 = new Promise(function(resolve,reject){
    //异步代码
    //resolve --成功了
    //reject --失败了
    $.ajsx({
        url:'arr.txt',
        dataType:'json',
        success(arr){resolve(arr)},
        error(err){reject(err)}
    })
})
//全都成功才算成功
Promise.all([p1,p2]).then(
 function(arr){
    let[res1,res2] = arr;
    alert('全部成功')},
    alert(res1)
    alert(res2)
 function(){
    alert('至少1个失败')
})
//简写,对Promise进行封装对象
function createPromise(url){
    return new Promise(function(resolve,reject){
    $.ajsx({
        url, //同名简写
        dataType:'json',
        success(arr){resolve(arr)},
        error(err){reject(err)}
    })
})
}

Promise.all([
    create('date/arr.txt'),
    create('date/json.txt')
]).then( function(arr){
    let[res1,res2] = arr;
    alert('全部成功')},
    alert(res1)
    alert(res2)
 function(){
    alert('至少1个失败')
})

jquery,天生带有Promise对象

//jquery,天生带有Promise对象
<script src="jquery.js" charset="utf-8"></script>
let p = $.ajax({url:'data/arr.txt',dataType:'json'})
console.log(p) //p已经封装了Promise

Promise.all([
    $.ajax({url:'data/arr.txt',dataType:'json'}),
    $.ajax({url:'data/json.txt',dataType:'json'})
]).then(function (results){
    let [arr,json]=results; 
    alert('成功了');
    console.log(arr,json); //接收到1个数组,1个json
},function (){
    alert('失败了')
})

Promise其他用法

  • Promise.all // 一个个全都得成功
  • Promise.race -竞速 , 谁先来了用谁

 

//比如5个资源,谁先来了用谁
Promise.race([
    $.ajax({url:'http://1.data'}),
    $.ajax({url:'http://2.data'}),
    $.ajax({url:'http://3.data'}),
    $.ajax({url:'http://4.data'}),
    $.ajax({url:'http://5.data'})
]); 

复习

 

 

11、generator-认识生成器函数

  • 中文是啥意思:
    • generat 【生成】
    • generator 【生成器】
  •  generator是一种特殊的函数,和普通的函数区别:
    • 普通函数 --》 一路到底,运行了中间就不会停
    • generator 函数 --》 中间能停 , 踹一脚走一步

 

//普通函数
function show(){
     alert('a');
     alert('b');
}
show(); //调用,一条路走到底


//星号,generator特点
function *show(){ 
    //*比较随意
       // function* show()  //星号和function一起
    // function  * show() //星号在中间
    
    alert('a');
    //需求,等待一会在往下走
    
    yiele;       //暂时放弃
    alert('b')
}
show()

len genObj = show(); //创建了generator 对象,不会直接执行函数内代码
console.log(genObj)  //输出object Generator
genObj.next()  //alert('a')
genObj.next() //alert('b')

适合场景

function *函数{
   代码...   
   yield ajax(xxx);  //什么时候数据回来了,接着走,【原先:写回调里面】
   代码...
}

背后实现

  • 如何实现走走停停,使用generator 生成一堆的小函数
function show_1(){
    alert('a')
}
function show_2(){
    alert('b')
}
next(); //第1次走show_1
next(); //第2次走show_2

总结

  • generator 简单来说就是能让函数走走停停
  • yield是整个generator里面最不好理解的一个东西,能不能把它掌握了,决定了generator学的好不好

 

 

12 、generator-yield是个啥

  • 重点:yield学好 ,generator也就学好
    • yield:放弃执行的意思
    • yield:既可以传参,也可以返回
//传参
function *show(){  //使用show(num1,num2)传参给 a
    alert('a')
    let a = yield //到这第一个next
    
    alert('b')
    alert(a) //5
} 
let gen = show();
gen.next(12); //第一个传参,都是废的,没法给yield传参
gen.next(5);

中间结果

//中间结果
function *show(){  
    alert('a')
    yield 12
    alert('b')
     return 55; //最终结果
} 
let gen = show();
let res1 = gen.next(12);  
console.log(res1) //{value:12,done:false}  //done意思是函数还没有走完
let res2 = gen.next(5);
console.log(res2) //{value:underfined,done:true}

举例:

 

function *炒菜(菜市场买回来的){
     洗菜 -> 洗好的菜   //第1步洗菜后结果:洗好的菜
    let 干净的菜 = yield 洗好的菜   //中间返回:洗好的菜
    干净的菜->切->丝               //干净的菜,切丝
    let 切好的菜 = yield 丝       //返回:切成丝的菜
    切好的菜 ->炒->熟的菜            
    return 熟的菜
}
*炒菜()