欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

es6 async和await

程序员文章站 2022-04-20 10:05:36
es7 async和await ,作为genertor函数语法糖,在使用上比generator函数方便的,Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用yield语句注明. generator将异步的流程标记的很简洁,但是流程执行却并不方便,所有 ......

  es7 async和await ,作为genertor函数语法糖,在使用上比generator函数方便的,generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用yield语句注明.

  generator将异步的流程标记的很简洁,但是流程执行却并不方便,所有我们需要借助generator的自执行下函数。thunk 函数可以用于generator函数的自流程管理

   async和await 作为generator的语法糖,自带自执行器,相对于generator具有更好的语义,yield后面只能时promise,async,await 具有更好的适用性,并不明确规定是promise,async的返回的是promise

  1.asycn和await的基本使用

    async如果遇到await就会等待,等待其执行结果,才会往下继续执行函数内部语句

/* 异步执行方法 */
function timeout(ms) {
    return new promise((res)=>{
        console.log('settimeout')
        settimeout(res,ms)
    })
}
/* await 只能在async定义的函数内部使用 */
async function asyncpriint(value,ms) {
    timeout(ms);
    console.log(value);
}
asyncpriint('hello world',2000);
// 先输出settimeout等待2m钟输出hello world
// 如果去掉await,输出settimeout并且不等待直接输出hello world

  async函数返回的是一个promise

/* async返回时最终会转成一个promise */
async function donow() {
    return 'czklove'
}
async function donow2 () {
    return new promise(res=>{
        res('czklove')
    })
}
async function donow3 () {
    return promise.resolve('czklove')
}
donow().then((val)=>{
    console.log(val)
})
// 输出czklove
donow2().then((val)=>{
    console.log(val)
})
// 输出czklove
/* 2和3是等价的,promise.resolve 返回一个promise */
donow3().then((val)=>{
    console.log(val)
})
//输出czklove
// 输出输出czklove
/* donow和donow2是等价的
    也就是说返回值是一个值的话,他会自动转化成promise
 */

  async返回的promise对象的状态变化

/* resolve */
async function promiseresolve(){
    await promise.resolve('czkloveresolve')
    return 'czklove1'
}
/* rejuect */
async function promisereject(){
    await promise.reject('czkloverejuct')
    console.log(123)
    return 'czklove2'
}
/* 内部都是resolve 
   一直执行下去
*/
promiseresolve().then(res=>{
    console.log('resolve'+res)
},rej=>{
    console.log('reject'+rej)
})
// resolveczklove1

/* 
    内部其中一个await是reject,则直接返回,不会再执行下去,并且返回值是rejuect的值
 */
promisereject().then(res=>{
    console.log('resolve'+res)
},rej=>{
    console.log('reject'+rej)
})
// 不会执行console.log(123)
// rejectczkloverejuct

  await  命令后面是一个promise对象,返回该对象的结果,如果不是promise,值直接放回该值

    如果后面是一个带有then 方法的对象,那么会将其等同于promise

    await 后面的promise如果执行了rejuect 则整个函数终止,并且返回该对象的结果,返回的promise对象的状态也是rejuect的

    如果我们想继续执行下去,则可以将reject的promise 放入try catch 模块中,另外一种是后面跟.catch 方法

/* 定义一个async 函数 */
async function awaitfc() {
    try {
        /* 放入try 和 catch 中 reject 不会终止函数执行 */
        await promise.reject('czklove')
    } catch (e){

    }
    /* .catch 也可以使 reject 不会终止函数执行*/
    await promise.reject('czklove').catch((e)=>{
        console.log(e)
    })
    return 'jgczklove'
}
awaitfc().then(val=>{
    console.log(val)
})
//czklove async.js

  函数的并发执行或继发执行

/* 定义一个async 函数 */
let i = 1;
function settime(ms) {
    return new promise((res)=>{
        settimeout(()=>{
            res ('123'+(i++))
        },ms)   
    })
}
/* 继发执行 */
async function funa() {
    let val1 = await settime(2000)
    console.log(val1)
    let val2 = await settime(2000)
    console.log(val2)
    let val3 = await settime(2000)
    console.log(val3)
    console.log('1111')
}
/* 并发执行 */
async function funa2() {
    let val1 = settime(2000);
    let val2 = settime(3000);
    let val3 = settime(2000);
    console.log(await val1)
    console.log(await val2)
    console.log(await val3)
    console.log(2222)
}
funa();
/* 
继发执行
结果是顺序的
    每隔2秒 输出1231 1232 1233 ,最终输出1111
*/
funa2();
/* 
并发
val1 val2 val3 输出结果顺序是不定的,但是可以确认,最终才输出2222
 */

  使用promise.all 也可以达到并发执行