• js中的同步异步问题


    异步:

    异步指的是一个任务分成两部分,先执行第一部分,然后再执行其他的任务,等第一部分执行完毕,再回来执行第二段

    相应的,连续的执行就叫做同步,由于是连续执行,不能插入其他任务,所以执行时只能等前面的任务完成之后才能执行后面的的任务。

    js中对异步编程的实现就是通过回调函数。回调函数就是把第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数

    如果要依次调用多个函数,就会出现多重嵌套。为了解决这种回调地狱的问题,可以使用Promise方法

    Promise提供then方法加载回调函数,catch方法捕捉执行过程中抛出的错误。

    Promise最大的问题是代码冗余,原来的任务被Promise包装之后,不管什么操作,看起来就是一堆的then,语句不够清晰。

    因此又出现了Generator函数

    执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,

    可以依次遍历Generator函数内部的每一个状态

    形式上,Generator函数是一个普通函数,但是有两个特征:

    1.function关键字与函数名之间有一个星号*

    2.函数体内部使用yield语句,定义不同的状态

    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    var hw = helloWorldGenerator();

    上述代码定义了一个Generator函数helloWorldGenerator,内部有两个yield语句“hello”和“world”,即该函数有三个状态 分别是 :hello,world和return语句(结束执行)

    Generator函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用Generator函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object)。

    所以必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句或return语句为止。

    Generator函数是分段执行的,yield语句是暂时执行的标记,而next方法可以恢复执行

    hw.next()
    // { value: 'hello', done: false }
    
    hw.next()
    // { value: 'world', done: false }
    
    hw.next()
    // { value: 'ending', done: true }
    
    hw.next()
    // { value: undefined, done: true }

    上面代码一共调用了四次next方法。

    第一次调用,Generator函数开始执行,直到遇到第一个yield语句为止。next方法返回一个对象,它的value属性就是当前yield语句的值hello,done属性的值false,表示遍历还没有结束。

    第二次调用,Generator函数从上次yield语句停下的地方,一直执行到下一个yield语句。next方法返回的对象的value属性就是当前yield语句的值world,done属性的值false,表示遍历还没有结束。

    第三次调用,Generator函数从上次yield语句停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。

    第四次调用,此时Generator函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。

    总结一下,调用Generator函数,返回一个遍历器对象,代表Generator函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着valuedone两个属性的对象。value属性表示当前的内部状态的值,是yield语句后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

    ES6没有规定,function关键字与函数名之间的星号,写在哪个位置。这导致下面的写法都能通过。但是一般使用第三种,星号紧跟在function关键字后面。

    function * foo(x, y) { ··· }
    
    function *foo(x, y) { ··· }
    
    function* foo(x, y) { ··· }
    
    function*foo(x, y) { ··· }
  • 相关阅读:
    Android:求职旺季,了解这份面试经验,自然无惧面试!
    2020上半年百度Android岗(初级到高级)面试真题全收录+解析,备战金九银十!(下篇)_chuhe1989的博客-CSDN博客
    泪目!阿里大佬国庆8天花了50个小时,整理出这份18万字Android-360°性能优化实战解析_chuhe1989的博客-CSDN博客
    Android程序员面试必须要掌握的:Https加密原理、中间人攻击到底是怎么回事_chuhe1989的博客-CSDN博客
    @HTTPS 原理分析——带着疑问层层深入
    @Android 换肤那些事儿, Resource包装流 ?AssetManager替换流?
    @腾讯面试官:说说王者荣耀里面Android的换肤原理和Android的皮肤,装载机框架解析
    @Android 无缝换肤深入了解与使用
    @Android的换肤原理和Android的皮肤,装载机框架解析
    @Android小技巧--switch控件的用法
  • 原文地址:https://www.cnblogs.com/150536FBB/p/12108501.html
Copyright © 2020-2023  润新知