目录↑

Promise、Generator、async/await用法

By blockXun

Promise、Generator、async/await都是用来解决异步编程的

Promise

    new Promise((resolve,reject) => {
        if (...) {
            resolve()
        } else {
            reject()
        }
    }).then(res => {
        ...
    }).catch(err => {
        ...
    })

promise对象一共有三个状态

  • 等待
  • 实现(resolve)
  • 失败(reject)

从创建开始,promise对象的状态就是等待的状态,直到resolvereject被调用

当promise被变成resolve时,会触发then()里的函数

当promise被变成reject时,会触发catch()里的函数 (也可以将err=>{...}写在then中,当做then的第二个形参传入,在reject时也会触发)

promise.all()

promise.all() 用于对多个promise打包成一个新的promise

promise.all接受一个数组,数组中是promise对象或其他值,当调用时,如果数组中有任何一个promise对象失败(reject),promise.all都会失败,走catch(有resolve的也会同时走then),返回值是失败的reject返回的信息

var a = function () {
    new Promise((resolve, reject) => {
        setTimeout(() => reject('这是错误返回信息'), 1000)
    })
}
var b = function () {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve('正确1'), 1000)
    })
}
var c = function () {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve('正确2'), 1000)
    })
}
Promise.all([c(), b(), a()]).then(res => {
    console.log(res)
}).catch(err => {
    console.error(err)
})

得到结果
输出的log

Promise.all会同时执行all中所有的promise对象,然后按顺序返回回来,所以上放代码调用时,用时1s多,并不是3s多

Generator

Generator函数是一个可以“暂停”的函数写法,可以通过对函数内部设置 “暂停”按钮 返回一个值并暂停函数执行,直到让他“开始”

Generator函数的创建方法是在函数后边添加一个*

function * fun () {
    ...
    yield xxx
    ...
    return xxx
}
// 或
var fun2 = function * () {
    ...
    yield xxx
    ...
    return xxx
}

在调用Generator函数时,并不会直接出发该函数,而是返回一个Generator对象,然后,通过Generator对象.next()来执行函数

  • “暂停”按钮: 在执行到yield的时候,会暂停该函数,并“return”出yield的内容,直到下次执行next()
  • “开始”按钮: 通过next()执行函数
  • next()返回值是一个对象,对象包含valuedone
    • value: 返回的值
    • done: Boolean值,如果为false,代表着是yield输出,还没有return(无论yield后函数中还有没有代码,都会返回false),如果为true,代表着此次输出是return或已经结束
function * fun () {
    yield 'xxx1'
    yield 'xxx2'
    yield 'xxx3'
    yield 'xxx4'
    return 'x'
}
var a = fun()
a.next()
a.next()
a.next()
a.next()
a.next()
a.next()

// {value: "xxx1", done: false}
// {value: "xxx2", done: false}
// {value: "xxx3", done: false}
// {value: "xxx4", done: false}
// {value: "x", done: true}
// {value: undefined, done: true}

next()中可以传值

function * fun () {
    var a = yield '函数中的字符串'
    console.log('log出来的内容: ' + a)
    return a
}
var a = fun()
a.next()
a.next()

 // {value: "函数中的字符串", done: false}
 // log出来的内容: 传输的字符串
 // {value: "传输的字符串", done: true}

async/await

async/await是一种处理promise的及其简便的方法

async函数返回的是一个promise对象,在async函数中,碰到await会等待,等待await后边的表达式的计算结果完成,这个表达式的计算结果可以是promise或者其他值(因为await可以等待表达式结果,所以可以等待react中的setState({})

async function fun () {
    await new Promise(resolve => {setTimeout(()=> resolve('111'), 1000)})
    console.log('111')
    return 'return值'
}
fun()
// ... 1秒后
// 111
fun().then(res => {console.log(res)})
// ... 1秒后
// 111
// return值

await可以和promise.all同时使用

function promiseFun1 () {
    return new Promise(resolve => setTimeout(resolve, 1000))
}
function promiseFun2 () {
    return new Promise(resolve => setTimeout(resolve, 1000))
}
function promiseFun3 () {
    return new Promise(resolve => setTimeout(resolve, 1000))
}
function promiseFun4 () {
    return new Promise(resolve => setTimeout(resolve, 1000))
}
async function runner () {
    return Promise.all([promiseFun1(), promiseFun2(), promiseFun3(), promiseFun4()])
}
async function go () {
    await runner()
    await console.log(1)
}
go()