首页 > 编程语言 >js异步编程的三种模式

js异步编程的三种模式

时间:2022-11-15 14:48:04浏览次数:61  
标签:info 异步 resolve 编程 js 任务 Promise 执行

写在前面

javascript语言的执行环境是"单线程"(single thread),就是指一次只能完成一件任务。如果有多个任务,就必须排队,等前面一个任务完成,再执行后面一个任务,以此类推。
 这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。

单线程

function f1() {
    console.log('1')
}
function f2() {
    console.log('2')
}
f1()
f2()

很容易可以看出,上述代码会依次输出1,2。因为代码是从上到下,依次执行,执行完f1(),才会执行f2()。但是如果f1()中的代码执行的是读取文件或者ajax操作呢,文件的读取都需要一定时间,难道我们需要完全等到文件完全读完再进行写操作么?为了解决这个问题,接下来我们来探究一下js中 同步和异步 的概念。

同步和异步

同步

  • 指在 主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。
  • 也就是调用一旦开始,必须这个调用 返回结果(划重点——)才能继续往后执行。程序的执行顺序和任务排列顺序是一致的。

异步

  • 异步任务是指不进入主线程,而进入 任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。
  • 每一个任务有一个或多个 回调函数。前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行。
  • 程序的执行顺序和任务的排列顺序是不一致的,异步的。
  • 我们常用的setTimeout和setInterval函数,Ajax都是异步操作。

那么如何实现异步编程呢,笔者介绍几种方法

回调函数(Callback)

回调函数,这是异步编程最基本的方法。

const fs = require('fs')
fs.readFile('./pakage.json',(err,info) => {
    fs.writeFile('./p.json',info,(err) => {
        if(!err) {
            setTimeout(() => {
                console.log('ok')
            },2000)
        }
    })
})

上述代码通过回调函数的嵌套,从文件系统中读取一个./pakage.json文件并写入./p.json,读取成功两秒后输出'ok'。用回调来实现异步,没有什么问题。
但是试想,如果再多几个异步函数,代码整体的维护性,可读性都变的极差,如果出了bug,修复过程也变的极为困难,这个便是所谓的 回调函数地狱

Promise对象

Promise对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。

MDN对Promise定义如上,Promise本意为承诺,我们可以理解为程序承诺过一段时间后会给你一个结果。
Promise是一个对象,可以保存三个状态 每一时刻必须有一个状态。

  • 成功 Fulfilled

  • 失败 Rejected

  • 处理中 Pending

  1. 默认 pending 如果调用 resolve fulfilled

  2. 默认 pending 如果调用 reject rejeced

    promise状态

const fs = require('fs')
const promise1 = new Promise((resolve,reject) => {
    fs.readFile('./package.json',(err,info) => {
        resolve(info)
    })
})
const promise2 = (info) => {
    new Promise((resolve,reject) => {
        fs.writeFile('./p.json', info,(err) => {
            if(!err) {
                resolve();
            }else{
                reject();
            }
        })
    })
}
const promise3 = (time) => {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve()
        },time)
    })
}
//then链式调用
//读文件成功 将结果作为参数传入promise2
promise1.then((info) => {
    return promise2(info)
})
.then(() => {
    // 等着前面的promise 
    console.log('读写完成')
    return promise3(2000)
})
.then( ()=> {
    console.log('ok')
})

参考视频讲解:进入学习

这么一看,并没有什么区别,还比上面的异步回调复杂,得先新建Promise再定义其回调。但其实,Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调。
 我们先使用new来构建一个promise。Promise接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
resolve:成功时调用,并将结果,作为参数传递出去;
reject:失败时调用,并将错误,作为参数抛出。

  • then方法接收两个函数作为参数,第一个参数是Promise执行成功时的回调,第二个 参数是Promise执行失败时的回调。
  • Promise对象的then方法返回一个新的Promise对象,因此所以可以通过链式调用then方法。

我们还可以继续优化一丢丢。

async+await 语法糖

直接上代码

async function run() {
    let info = await promise1;
    await promise2(info);
    await promise3(2000);
    console.log('ok');
}

async函数是在ES2017 标准中引入的,使我们异步的代码更加优雅了。这里使用async+await 代替了.then()方法。

  • async必须在函数声明前
  • await 接一个 promise,那么后面的代码就会等待,等promise resolve了才会执行。

标签:info,异步,resolve,编程,js,任务,Promise,执行
From: https://www.cnblogs.com/hellocoder2029/p/16892346.html

相关文章

  • umi配置chainWebpack,使用自定义loader----jsx-px2rem
    前言虽然云谦大佬在github上说了,umi本身的配置已经很完善了,但是肯定满足不了所有人各种各样的奇葩需求。。。比如今天说的将jsx中的style里,将px转换为rem。 umi本身提......
  • js函数式编程讲解
    什么是函数式编程是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简......
  • 彻底搞懂nodejs事件循环
    nodejs是单线程执行的,同时它又是基于事件驱动的非阻塞IO编程模型。这就使得我们不用等待异步操作结果返回,就可以继续往下执行代码。当异步事件触发之后,就会通知主线程,主线......
  • 一文读懂NodeJs知识体系和原理浅析
    node.js初探Node.js是一个JS的服务端运行环境,简单的来说,它是在JS语言规范的基础上,封装了一些服务端的运行时对象,让我们能够简单实现非常多的业务功能。如果我们只......
  • nodejs实现jwt
    jwt是jsonwebtoken的简称,本文介绍它的原理,最后后端用nodejs自己实现如何为客户端生成令牌token和校验token1.为什么需要会话管理我们用nodejs为前端或者其他服务提供......
  • 直播软件app开发,js 表单验证,登录注册
     直播软件app开发,js表单验证,登录注册<!DOCTYPEhtml><html> <head>  <metacharset="UTF-8">  <metahttp-equiv="X-UA-Compatible"content="IE=edge">  ......
  • 解决 vue 项目一直出现 sockjs-node/info?t=1554978**** ,并造成浏览器不能及时更新编
    首先sockjs-node是一个JavaScript库,提供跨浏览器JavaScript的API,创建了一个低延迟、全双工的浏览器和web服务器之间通信通道。服务端:sockjs-node(https://github.com/......
  • 解决 vue 项目一直出现 sockjs-node/info?t=1554978****问题【转载】
    首先先上图 看到很多人都是这么干的:1.找到/node_modules/sockjs-client/dist/sockjs.js2.找到代码的1605行try{//self.xhr.send(payload);把这......
  • Node.js多版本管理-nvm
    nvm可实现多版本管理,即一台开发电脑安装多个版本node.js然后根据项目需要的不同版本来切换。1、下载nvmhttps://github.com/coreybutler/nvm-windows/releases我这里选......
  • android实现json的解析
    新建一个Person类/***CreatedbyMr.Chan*Time2022-11-15*Bloghttps://www.cnblogs.com/Frank-dev-blog/*/publicclassPerson{privateStringid......