异步待修改

100 阅读3分钟

关于Generator 函数

es6提供的一种异步编程解决方案

function* hellogenerator() {
    yied 'hello';
    yied 'word';
    return 'ending';
}
let hg = hellogenerator();
// 在调用generator函数后函数不执行,返回的是一个内部状态的指针对象,必须调用next 才能让指针移到下一个状态   hg.next() // {value: 'hello', done: false}

如果没有 return 的话,则返回的值为 {value: 'undefined', done: true} done 是一个布尔值,表示是否结束,为false 就表示下面还有要运行的数据,如果一直调用next 的话,则当函数里面的全部执行完之后,后面就会一直是 {value: 'undefined', done: true}

遇到yied 表达式,就暂停执行后面的操作,并将紧跟在yied 后面的那个表达式的值作为返回的对象的value值,下一次调用next 方法时,再继续往下执行遇到下一个yield 表达式,如果没有遇到,则一直到函数结束,到return 语句为止,将return 语句后面表示的值 作为value 值,如果没有return 则 返回的是undefined

// yield表达式如果在另一个表达之中,则yield 表达式必须放在圆括号里面
function* demo() {
    console.log('hello' + (yield 123))
}

next 里面可以传递参数,next 里面的 参数代表 上一个 yield 表达式的返回值, 所以,在第一次next 方法里面传参数的时候,参数是无效的,只有第二次使用next 方法开始,参数才是有效的

function* foo(x) {
    var y = 2 * (yield ( x + 1 ));
    var z = yield(y / 3);
    return (x + Y + z);
}
var b = foo(5)
b.next() // 6
b.next(12)  // 12 * 2 / 3   //  8
b.next(13) //  y = 24    z = 13  x = 5  // 42 

关于async 和 await

解决了promise 的.then 的链式调用问题,属于对Generator函数的改进,将Generator函数的星号 替换成了async, 将 yield 替换成了 await

await 必须写在async函数的里面。

await 后面跟的是一个promise

async 函数返回的是一个promise 对象

let resultasync = async function test() {
    return "hello"
}()
console.log(resultasync)  // 返回一个promise对象 
// 所以可以用点then 获取值
resultasync.then( s => console.log(s) ) // hello
// 如果 async 函数没有返回值的话,则会返回一个promise.resolve(undefined), Promise函数是立即执行的,所有,在没有await 的情况下,async 函数会立即执行并且返回一个promise 对象,不会阻塞后面的语句

await 是一个运算符,他等待的是一个表达式,这个表达式计算结果是promise对象或者其他值,一般来说是等async 函数的完成,等待一个返回值,如果等到的不是一个Promise对象的话,那么await 表达式的运算结果就是他要等到的东西,如果等到了一个promise对象的话,他就会阻塞后面的代码,等待这个promise 对象的 resolve ,然后将得到的resolve的值作为表达式的运算结果。

function fn () {
    return new Promise(resolve => {
        console.log(1)
        // resolve()
    })
}
async function fn1() {
    await fn();
    console.log(2)
}
fn1();
console.log(3)
// 分析: fn1()执行的时候,fn 是同步的,所以会打印出 1, 然后 打印 3,await等到了一个promise对象 但是fn 没有resolve 结果,await 就取不到值,就一直等待,所有 2 不会打印 

await 命令之后的Promise 对象,运行结果可能是 rejected , 所有,最好把await 命令放在 try...catch 中。

async function myFunction() {
    try {
        await somethingThatPromise();
    } catch (err) {
        console.log(err)
    }
}
// 其他写法
async function myFunction() {
    await somethingPromise().catch(function (err){
        console.log(err);
    } )
}

关于Promise