zoukankan      html  css  js  c++  java
  • JS异步

    • 单线程

      JS是单线程,一次只能做一件事,如果同一时间有多个任务的话,这些任务需排队,前一个任务执行完才会执行后一个任务。

      JS为什么是单线程,这与JS用途有很大关系,JS是浏览器脚本语言,主要用来实现与用户交互,利用JS可以实现对DOM的各种操作,如果是多线程会带来很复杂的同步问题

    • 为什么需要异步

      JS 为单线程同一时间只能处理同个任务,但如果前一个任务执行时间很长,如文件读取和 ajax 操作,后一个任务就不得不等着,严重影响用户体验。JS 的异步就是先挂起处于等待中的任务,先运行排在后面的任务,等到文件读取或 ajax 有了结果后再回头执行挂起的任务

      异步任务指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程,如图片、音乐的加载。

    • 异步机制

      异步如何实现,回调和事件循环。

      任务队列:异步任务不会进入主线程,而是先进入任务队列,任务队列是一个先进先出的数据结构,一个异步任务结束就会在任务队列中添加事件,即可以进入执行栈。但此时的主线程不一定有空,当主线程处理完其他任务队列有空时,就会读取任务队列,读取里面有哪些事件,前面的事件会被优先处理,如果该任务指定了回调函数,就会执行回调函数中的代码。

      单线程从任务队列中读取任务是不断循环的,每次栈被清空后,都会在任务队列中的读取新的任务,这就叫做任务循环,因每个任务都由一个事件触发,因此也叫事件循环。

      JS异步机制步骤

      1. 所有同步任务都在主线程上执行,形成执行栈
      2. 主线程外,还存在一个任务队里,只有异步任务有了结果,就会在任务队列中放置一个事件
      3. 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,看看里面有哪些事件,对应的异步任务结束等待状态,进入执行栈,开始执行。
      4. 主线程不断重复第三步
    • 异步编程

      • 回调函数

        一个函数(回调函数)作为参数传递给另一个函数,并在函数中被调用

        使用 ajax 时,我们就用到了回调函数实现的异步

        var req = new XMLHttpRequest()
        req.open("GET",url)
        req.send(null)		//异步任务
        req.Onreadystatechange = function(){}	//事件回调,得到相应之后触发该事件
        

        还要像 setTimeout

        回调函数容易形成回调炼狱,不利于代码阅读

      • Promise

        ES6.0 新增的异步对象

        • Promise 是一个构造函数,既然是构造函数,那么我们就可以 new Promise() 得到一个 Promise 实例

        • 在 Promise 上,有两个函数,分别叫做 resolve (成功之后的回调函数) 和 reject (失败之后的回调函数)

        • 在 Promise 构造函数的 Prototype 属性上,有一个 .then() 方法,也就是说,只要是 Promise 函数构造创建的实例,都可以访问到 .then方法

        • Promise 表示一个异步操作,当我们 new Promise 实例,这个实例就表示一个具体的异步操作

        • 既然 Promise 创建的实例是一个异步操作,那么这个异步操作的结果,只能有两种状态:

          1. 状态1:异步执行成功了,需要在内部调用成功的回调函数 resolve 把结果返回给调用者

          2. 状态2:异步执行失败了,需要在内部调用失败的回调函数 reject 把结果返回给调用者

          3. 由于 Promise 实例是一个异步操作,所以内部拿到操作的结果后,无法使用 return 把操作的结果返回个调用者;这时候,只能使用回调函数的形式,来把成功或失败的结果,返回给调用者

        • 们可以在 new 出来的 Promise 实例上调用.then() 方法,预先为这个 Promise 异步操作,指定成功和失败的回调函数

      • 用 Promise 封装读取文件操作

        function getFileByPath(fpath){
            return new Promise(function (resolve,reject) {
                fs.readFile(fpath, 'utf-8', (err,dataStr) => {
                    if(err) return reject(err)
                    resolve(dataStr)
                })
            })
        }
        getFileByPath('./11.txt').then(function(data){
            console.log(data+'访问成功')
        },function (err) {
            console.log(err.message+'访问失败')
        })
        
  • 相关阅读:
    html 时间区间选择功能
    Django 【settings】数据库设置
    Django forms 定制form字段
    避免js全局变量污染的方法
    js获取路由
    采用遍历的方法获取字符串a在字符串b中的位置
    vue 学习笔记
    Promise
    js常用JSON数据操作
    js 数组遍历方式
  • 原文地址:https://www.cnblogs.com/angle-yan/p/13365745.html
Copyright © 2011-2022 走看看