zoukankan      html  css  js  c++  java
  • 每日技术:Promise和Async/Await用法

    Promise

    Promise是一个容器,里面保存着某个未来才会结束的时间(通常是一个异步操作的结果)

    Promise对象的基本语法:

    let p = new Promise((resolve, reject) => {
        // ...
        resolve('success')
    })
    
    p.then(res => {
        console.log(res); // success
    })

    Promise对象特点和三个状态:

    1. 对象的状态不受外界影响
    2. 一旦状态改变,就不会再变,状态会被凝固。

    例如:

    let p = new Promise((resolve, reject) => {
        // ...
        resolve('success')
        console.log('after resolve')
        reject('error')
    })
    
    p.then(res => {
        console.log(res); // success
    })
    
    p.catch(err => {
        console.log(err)
    })
    
    // 运行结果:after resolve -> success

    resolve下面的语句其实是可以执行的,那么为什么reject的状态信息在下面没有接收到呢?这就是因为Promise对象的状态凝固了。

    new出一个Promise对象时,这个对象的起始状态就是Pending状态,再根据resolve或reject返回Fulfilled状态/Rejected状态。

    Promise.prototype.then 的作用是为Promise实例添加状态改变时的回调函数。可以有两个参数

    • .then(func1, func2)
    • .then(func1)
    • .then(null, func2)

    Then分别接受resolve, reject的信息

    let p = new Promise((resolve, reject) => {
        // ...
        let random = Math.random(); //小于1大于0
        if (random > 0.4) {
            resolve('random > 0.4');
        } else {
            reject('random <= 0.4');
        }
    })
    
    p.then(res => {
        console.log('resolve', res)
    }, res => {
        console.log('reject', res)
    })

    Promise.resolve() 

    Promise.resolve() 将现有对象转为Promise对象的快捷方式

    let p1 = Promise.resolve({name: 'xixi', age: 18})
    
    p1.then(result => {
        console.log(result)
    })

    如果是Promise对象,直接返回

    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('success')
        }, 500)
    })
    
    let pp = Promise.resolve(p)
    
    pp.then(res => {
        console.log(res)
    })
    
    console.log(pp == p)
    
    // 输出结果:true -> success

    Promise.reject() 

    Promise.reject() 快速地获取一个拒绝状态的Promise对象

    let p = Promise.reject(123)
    console.log(p)
    
    p.then((res) => {
        console.log(res)
    }).catch(res => {
        console.log('catch', res)
    })
    
    // 输出结果:Promise {<rejected> 123} -> catch 123

    Promise.all()

    let p1 = Promise.resolve(123);
    let p2 = Promise.resolve('hello');
    let p3 = Promise.resolve('success');
    
    Promise.all([p1, p2, p3]).then(result => {
        console.log(result);
    })
    
    // 结果:[123, 'hello', 'success']

    当所有的状态都是成功状态才返回数组,否则返回reject的状态。

    再来一个例子,用sleep模仿浏览器的AJAX请求

    function sleep(wait) {
        return new Promise((res, rej) => {
            setTimeout(() => {
                res(wait)
            }, wait)
        })
    }
    
    let p1 = sleep(500)
    let p2 = sleep(500)
    let p3 = sleep(1000)
    
    Promise.all([p1, p2, p3]).then(result => {
        console.log(result)
        // ...
        // loading
    })

    Promise.race() 

    Promise.race() 将多个Promise实例,包装成一个新的Promise实例。哪个对象返回的快就返回哪个对象。race最终只有一个值。

    Async-Await

    简介

    异步编程的最高境界,就是根本不用关心它异步。

    async函数就是隧道尽头的亮光,很多人认为它是异步操作的终极解决方案。

    async-await与promise的关系

    不存在谁替代谁的,因为async-await是寄生于Promise,Generator的语法糖

    规则:

    1. async表示这是一个async函数,await只能用在这个函数里面
    2. await表示在这里等待promise返回结果后再继续执行。
    3. await后面跟着的应该是一个promise对象

    应用

    Promise虽然一方面解决了callback回调地狱,但是相对的把回调“纵向发展”了,形成了一个回调链。

    举例:

    function sleep(wait) {
        return new Promise((res, rej) => {
            setTimeout(() => {
                res(wait)
            }, wait)
        })
    }
    
    sleep(100).then(result => {
        return sleep(result + 100)
    }).then(result02 => {
        return sleep(result02 + 100)
    }).then(result03 => {
        console.log(result03)
    })
    
    // 结果:300

    后面的结果都是依赖前面的结果,改写async/await写法如下:

    async function demo() {
        let result01 = await sleep(100)
        let result02 = await sleep(result01 + 100)
        let result03 = await sleep(result02 + 100)
    
        return result03
    }
    
    demo().then(result => {
        console.log(result)
    })
    
    // 结果:300

    错误处理

    既然.then()不用写了,那么catch()也不用写了,可以直接用标准的try catch语法捕捉错误

    如果是reject状态,可以用try-catch捕捉

    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('error')
        }, 1000)
    })
    
    async function demo(params) {
        try {
            let result = await p
        } catch(e) {
            console.log(e)
        }
    }
    
    demo()

    注意你的并行执行和循环

    await in for循环

    await的执行上下文必须是async函数

    如果在forEach或者map的循环里使用await,这时候上下文就变成了array,而不是async function 就会报错。

    以上笔记摘自:https://www.jianshu.com/p/fe0159f8beb4

  • 相关阅读:
    文件处理
    基本数据类型
    Python简介和入门
    了解计算机的发展历程
    工具类(MailUtils)发邮件
    文件上传和下载
    JavaWeb过滤器
    JavaWeb监听器
    JavaWeb的分页
    JdbcUtils(内部使用c3p0得到连接池对象datasource)的第三次修改---完成事务的处理
  • 原文地址:https://www.cnblogs.com/cathy1024/p/11227659.html
Copyright © 2011-2022 走看看