JavaScript异步编程几种方式

前言

    JavaScript程序执行是单线程,既程序按顺序一步一步向下执行,后面的程序必须等前面的程序执行完毕,这样容易形成程序阻塞,浪费CPU资源,浏览器容易进入假死状态(无响应),用户体验差,这时异步编程相应而出...ajax

一  回调函数(callback)

   回调函数是做为函数参数形式来执行的, 它是最基础的异步执行方法,让咱们看一个例子,编程

定义三个函数,fun2利用setTimeout实现异步函数,执行结果分别是1,3,2数组


当咱们但愿输出1,2,3时,fun3输出的顺序依赖fun2时,咱们能够把fun3做为fun2的回掉函数promise


fun2(fun3)复制代码

若后者等待前者的执行结果,采用这种方式,咱们把同步操做变成了异步操做,fun2便不会堵塞程序运行,至关于先执行程序的主要逻辑,将耗时的操做推迟执行。浏览器

二 Promise

在传统的ajax请求中,当异步请求之间的数据存在依赖关系的时候,就可能产生多层的回调fun1(fun2(fun3(fun4(...)))),这样会使代码逻辑很容易形成混乱不便于阅读和后期维护。另外一方面,每每错误处理的代码和正常的业务代码耦合在一块儿,形成代码会极其难看。为了让编程更美好,咱们就须要引入 promise来下降异步编程的复杂性。

它每个异步任务返回一个Promise对象,该对象有一个then方法,容许指定回调函数,即:bash

fun2.then(fun3)
fun2.then(fun3).then(fun4)//能够指定多个回掉函数
fun2.then(fun3).fail(fun4)//指定发生错误时的回调函数复制代码

ES6规定,Promise对象是一个构造函数,用来生成Promise实例。Promise构造函数接受一个函数做为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由JavaScript引擎提供,不用本身部署。异步

resolve函数负责把promise状态从“未完成”到“完成”(Pending 到Resolved),且异步函数执行成功后把状态做为参数传递出去;reject函数把promise状态从“未完成”到“失败”async

Promise实例生成之后,能够用then方法分别指定Resolved状态和Reject状态的回调函数。then方法接收两个回掉函数做为参数,一个是Promise对象为Resolved状态时调用,另外一个是为Rejected(可选)状态时调用。异步编程

promise.then(function(value) {
  // success
}, function(value) {
  // failure
});
复制代码

Promise.prototype.then()

     then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。所以能够采用链式写法,即then方法后面再调用另外一个then方法。函数

Promise.prototype.catch()

   Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

Promise.all()

   Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。Promise.all方法接受一个数组做为参数,每一个数组也是一个新到promise,当状态都为Resolve时,有一个为rejected,返回的promise状态就变成rejected

三 async/await

    async 会将其后的函数(函数表达式或 Lambda)的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise (也能够是任意表达式)完成,并将其 resolve 的结果返回出来。

function fun1 () {  console.log('1')}
function fun2 () {  return new Promise((resolve, reject) => {    setTimeout(() => {      console.log('2')      resolve()    }, 500)  })}
function fun3 () {  console.log('3')}
async function asyncFun () {  fun1()  await fun2()  fun3()}asyncFun()复制代码
相关文章
相关标签/搜索