前端异步流程工具

前端异步流程工具

1. 为什么要进行异步操作?
javascript是单线程,依次执行一个任务,要想让任务能够顺利进行,我们需要排队
异步就是将任务放入异步队列,在主线程执行结束之后再去执行
2. 前端异步的操作方式
传统方式
○ 回调函数
○ 事件
3.前端异步流程工具 【 封装出来函数、库 】
△ es6 Promise
含义:
(1)Promise 是异步编程的一种解决方案,比传统的解决方案–回调函数和事件--更合理和更强大。所谓Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。
(2)创建promise实例对象,构造函数的参数是一个函数对象,函数对象里面又有两个参数,一个代表成功的回调,一个是失败的回调

 let promise = new Promise(function(resolve, reject) {})

构造函数的参数是一个函数对象function(resolve, reject) { },函数对象里的两个参数也是函数:resolve和reject函数
(3)promise原型下面两个常用的方法:

Promise.prototype.then/Promise.prototype.catch
let promise=new Promise();//新建一个promise实例对象。
promise.then();//状态设为成功(已解决)时触发的方法
promise.catch();//状态设为失败(未解决)时触发的方法

Promise 对象的状态不受外界影响
三种状态:
pending:进行中
fulfilled :已经成功
rejected 已经失败
状态改变:
Promise对象的状态改变,只有两种可能:
从pending变为fulfilled
从pending变为rejected。
这两种情况只要发生,状态就固定,不能改变,这时就称为resolved(已定型)

基本用法:
异步操作:

//创建一个promise实例

    const p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('任务一')
            }, 2000)
    
        }).then(data => {
            console.log(data)
        }).catch(error => {
            if (error) throw error //抛错
        }) //p1处在队列中

//创建另一个promise实例
const p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('任务二')
        }, 1000)
    }).then(data => {
        console.log(data)
    }).catch(error => {
        if (error) throw error //抛错
    }) //p2处在队列中
    
console.log('主线程') //主线程

输出结果顺序为:主线程、任务二、任务一

promise的两个静态方法:

☆ Promise.all([promise实例1,promise实例2],·······)
all中,一次执行任务,即使有延时任务,也必须等待延时任务结束,后续任务才能进行
如果在上述代码块加上如下代码:

Promise.all([p1, p2]).then(() => {
  console.log('任务三')
})

那么最终输出结果为:主线程、任务二、任务一、任务三

☆ Promise.race([promise实例1,promise实例2],·······)
race指的是 任务快 的先进行,其他延时任务后续进行
如果在上述代码块加上如下代码:

Promise.race([p1, p2]).then(() => {
    console.log('任务三')
})

那么最终输出结果为:主线程、任务二、任务三、任务一

△ es6 Generator函数

含义:
在异步编程中,还有一种常用的解决方案,它就是Generator生成器函数。顾名思义,它是一个生成器,它也是一个状态机,内部拥有值及相关的状态,生成器返回一个迭代器Iterator对象,我们可以通过这个迭代器,手动地遍历相关的值、状态,保证正确的执行顺序。

基本用法:
Generator的声明方式类似一般的函数声明,只是多了个*号,并且一般可以在函数内看到yield关键字

function* p1() {
    yield '任务一'
    yield '任务二'
    yield '任务三'
    yield '任务四'
    return '任务五'
}
const task = p1();
console.log(task.next())
console.log(task.next())
console.log(task.next())
console.log(task.next())
console.log(task.next())

(1) 如上代码,定义了一个p1的生成器函数,调用之后返回了一个迭代器对象(即task)
调用next方法后,函数内执行第一条yield语句,输出当前的状态done(迭代器是否遍历完成)以及相应值(一般为yield关键字后面的运算结果)
(2) 每调用一次next,则执行一次yield语句,并在该处暂停,return完成之后,就退出了生成器函数,后续如果还有yield操作就不再执行了
切记输出结果为对象:如此处的输出
value 表示任务执行的结果
done 表示总任务执行状态

△ es6 - es8 async 函数
含义:
ES2017 标准引入了 async 函数,使得异步操作变得更加方便。
在异步处理上,async 函数就是 Generator 函数的语法糖。async函数就是将 Generator 函数的 * 替换成async,将yield替换成await。
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

基本用法:
async函数声明:
普通函数声明:async function fn( ){ }
赋值式声明:const fn=async function( ){ }
箭头函数声明:const fn=async( ) = > { }
例:

async function fn1() {
    return await '任务一'
}


const fn2 = async function() {
    return await '任务二'
}

const fn3 = async() => {
    return await '任务三'
}
fn1().then(res => { console.log(res) })
fn2().then(res => { console.log(res) })
fn3().then(res => { console.log(res) })
console.log('任务四')

输出结果:任务四、任务一、任务二、任务三

对async函数的理解:
1.async 表示这是一个 async 函数,而await存在于async函数内部,是一个关键字;
2.await 表示在这里等待 await 后面的操作执行完毕,再执行下一句代码。

△ Node中的异步处理工具: nextTick setImmediate
含义:
1.setImmediate()的使用
即时计时器立即执行工作,它是在事件轮询之后执行,为了防止轮询阻塞,每次只会调用一个。
2.process.nextTick()的使用
它和setImmediate()执行的顺序不一样,它是在事件轮询之前执行,有一个默认process.maxTickDepth=1000来限制事件队列的每次循环可执行的nextTick()事件的数目。

基本用法:

process.nextTick( () => {
  console.log('A')
})

setImmediate(() => {
  console.log('C')
})

process.nextTick( () => {
  console.log('B')
})


console.log( '主线程任务' )

输出结果:主线程,A,B,C

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值