每日技术:Promise和Async/Await用法

 

Promise

Promise是一个容器,里面保存着某个将来才会结束的时间(一般是一个异步操做的结果)编程

Promise对象的基本语法:数组

let p = new Promise((resolve, reject) => {
    // ...
    resolve('success')
})

p.then(res => {
    console.log(res); // success
})

Promise对象特色和三个状态: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对象的状态凝固了。dom

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

Promise.prototype.then 的做用是为Promise实例添加状态改变时的回调函数。能够有两个参数async

  • .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对象,直接返回spa

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

相关文章
相关标签/搜索