乐趣区

关于async-await:async和await原理

generator

async 和 await 是 generator 的语法糖,想要搞清楚 async 和 await 必须晓得 generator; 那么咱们先来看看 generator 函数;

function * getAge() {
    yield 1;
    yield 2;
}
let gen = getAge();
console.log(gen.next());//{value: 1, done: false}
console.log(gen.next());//{value: 2, done: false}
console.log(gen.next());//{value: undefined, done: true}

generator 和一般函数的区别:
1.generator 申明函数之前要加 *
2. 函数中有 yield,能够管制函数的运行

generator 传参问题
function * getAge() {
    let a = yield 1;
    console.log(a);//444
    yield 2;
}
let gen = getAge();
console.log(gen.next());
console.log(gen.next(444));

generator 传参能够将参数传在 next 函数中,给 a 赋值, 然而第一个 next() 函数永远是 undefined; 如下

function * getAge(xxx) {
    let a = yield 1;
    console.log(a);//undefined
    yield 2;
}
let gen = getAge();
console.log(gen.next(444));
console.log(gen.next());
generator 函数运行过程

generator 实现读取异步函数

当初有一个 name 和 age 的 txt 文件,咱们通过 name.txt 读取 age.txt 里的内容; 我这里的 name 中写的是 age.txt,age.txt 中写的是 18;

let {promisify} = require('util');
let fs = require('fs');
let read = promisify(fs.readFile);
function * getAge() {let name = yield read(`${__dirname}name.txt`, 'utf-8');
    let age = yield read(`${__dirname}${name}`, 'utf-8');
}
let it = getAge();
let {value} = it.next();// 返回的是读取 name.txt 的 promise 函数
value.then(data => {let {value} = it.next(data)// 将读取 name 文件的内容作为参数赋值给 getAge 函数中的 name, 同时这里的 value 是读取 age.txt 的 promise 函数
    value.then(data => {console.log(data)//18
    })
});

async 和 await

下面层层嵌套看着很乱尤其是嵌套多的状况下,那么咱们应用 async 和 await 实现一下这里只是将 generator 函数中的 * 换成了 async,将 yield 换成了 await

async function getAge1() {let name = await read(`${__dirname}name.txt`, 'utf-8');
    let age = await read(`${__dirname}${name}`, 'utf-8');
    console.log(age);
}
getAge1()

咱们将下面函数进行 babel 本义成 es2015,就是将 generaotr+promise 联合起来实现了 async 和 await 函数

1 将 async 函数转换成 generator
2. 第一次执行 next 传参为 undefined,下面咱们也提到了第一次 next 的值是 undefined
3. 将上一次的返回值传递给上面的 next 函数,递归实现找打最初即可

let {promisify} = require('util');
let fs = require('fs');
let read = promisify(fs.readFile);
function asyncGeneratorStep(gen, resolve, reject, _next, key, arg) {
    try {var info = gen[key](arg);
        var value = info.value;
    } catch (error) {reject(error);
        return;
    }
    if (info.done) {resolve(value);
    } else {
    // 为了避免 value 是个一般值(不是 promise), 应用 Promise.resolve 包一层
        Promise.resolve(value).then(_next);
    }
}
function _asyncToGenerator(fn) {return function () {return new Promise(function (resolve, reject) {var gen = fn();
            function _next(value) {asyncGeneratorStep(gen, resolve, reject, _next, "next", value);
            }
            _next(undefined);
        });
    };
}
function getAge1() {return _getAge();
}
function _getAge() {_getAge = _asyncToGenerator(function* () {let name = yield read(`${__dirname}name.txt`, 'utf-8');
        let age = yield read(`${__dirname}${name}`, 'utf-8');
    });
    return _getAge();}
getAge1(); // 让函数执行 
退出移动版