async和await是generator的語法糖,想要搞清楚async和await必須知道generator;那麼咱們先來看看generator函數;promise
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,能夠控制函數的運行babel
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());
如今有一個name和age的txt文件,咱們經過name.txt讀取age.txt裏的內容;我這裏的name中寫的是age.txt,age.txt中寫的是18;async
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實現一下這裏只是將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函數ui
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(); //讓函數執行