• js三座大山之三:异步和单线程


    单线程

    首先我们要知道,js这门语言是单线程的,同时只能做一件事,比如说渲染dom,执行js方法,这些事情只能一个一个做,不能分开执行。(因为js需要操作dom,当两个js方法同时操作一个dom的时候就会出问题,所以js被设计成了单线程)

    但是我们在开发中,遇到请求网络,或者定时任务的时候,如果等待网络请求结束或者定时任务结束的时候再去做其他事情,这样页面就会卡住,所以js有异步机制解决这个问题。

    异步

    异步的特点是不会阻塞后面的代码执行,当同步任务执行完毕之后,再执行异步任务。相对的,同步会阻止代码执行。异步任务的应用主要有网络请求和定时任务。

    异步是通过callback的方式实现的,在callback里面执行异步执行的代码,但是有一些场景比如我们有三个网络请求abc需要依次执行,在a的回调里发起b请求,在b的回调里发起c请求,这样会造成一种很混乱的写法,称之为回调地狱,可以试想一下,如果页面逻辑过于复杂,需要依次调用10个接口,那么代码的可读性会非常非常差,我们如果看到了别人的这种代码难免内心奔跑一万只神兽。

    promise基本用法:

        let fun1 = function(flag){
          return new Promise((resolve,reject)=>{
            if(flag){
              setTimeout(() => {
                resolve("success")
              }, 1000);
            }else{
              setTimeout(() => {
                reject("fail")
              }, 1000);
            }
          })
        }
       fun1(true).then((res)=>{ console.log(res)//success }).catch((res)=>{ console.log(res) }) fun1(false).then((res)=>{ console.log(res) }).catch((res)=>{ console.log(res)//fail })

    上面是一个最简单的promise函数,promise函数返回一个Promise对象,参数是一个函数,接收两个参数resolve和reject,这两个参数也是函数,当执行resolve()或者reject()的时候,函数返回.

    如果执行了resolve(),就会在调用的时候执行then()方法,并接收resove()返回的参数;

    如果执行了reject(),就会在调用的时候执行catch()方法,并接收reject()返回的参数;

    用promise重新实现一下上面三个网络请求的问题:

        let callService = function(url){
          return new Promise((resolve,reject)=>{
              axios.get(url).then((res)=>{
                resolve(res)
              }).catch((err)=>{
                reject(err)
              })
          
          })
        }
        const url1 = "/user/url1"
        const url2 = "/user/url2"
        const url3 = "/user/url3"
        callService(url1).then((res)=>{
          // do something
          return callService(url2)
        }).then(()=>{
          // do something
          return callService(url3)
        }).then((res)=>{
          // do something
        }).catch((err)=>{
          console.log(err)
        })  

    用上面的写法重新实现之后,写法上只会有一层,而不会陷入层层的回调之中。

    promise.all

    promise.all可以将多个promise包装成一个新的实例,成功的时候返回一个数组,谁先失败返回谁的值。

    promise.all方法可以帮我们处理日常开发中多接口同时调用的处理问题。

    let p1 = new Promise((resolve, reject) => {
      resolve('成功了')
    })
    
    let p2 = new Promise((resolve, reject) => {
      resolve('success')
    })
    
    Promise.all([p1, p2]).then((result) => {
      console.log(result)               //['成功了', 'success']
    }).catch((error) => {
      console.log(error)
    })

    promise.race

    这个方法的作用是多个接口赛跑,哪个跑得快就返回哪个

    Promise.race([p1, p2]).then((result) => {
      console.log(result)
    }).catch((error) => {
      console.log(error) 
    })
  • 相关阅读:
    求两个数的最大公约数--简单
    输入7个人的成绩,找出大于平均成绩的值--简单
    回文--简单
    约瑟夫环--中等难度
    数组中查找最大数和次大数--简单
    Docker在云环境中的应用实践初探:优势、局限性与效能评测
    基于mongoDB的capped collection的性能优化
    微软开放技术(中国)携 CKAN 和 OData 技术引入基于 Azure 的开放数据平台
    ThreadPoolExecutor原理及使用
    通过 Azure Media Encoder 降低编码成本
  • 原文地址:https://www.cnblogs.com/panda-programmer/p/13024092.html
Copyright © 2020-2023  润新知