1.async 函数是什么?一句话,它就是 Generator 函数的语法糖。
const fs = require(‘fs‘); const readFile = function (fileName) { return new Promise(function (resolve, reject) { fs.readFile(fileName, function(error, data) { if (error) return reject(error); resolve(data); }); }); }; //Generator 函数 const gen = function* () { const f1 = yield readFile(‘/etc/fstab‘); const f2 = yield readFile(‘/etc/shells‘); console.log(f1.toString()); console.log(f2.toString()); }; //async函数 const asyncReadFile = async function () { const f1 = await readFile(‘/etc/fstab‘); const f2 = await readFile(‘/etc/shells‘); console.log(f1.toString()); console.log(f2.toString()); };
async
函数就是将 Generator 函数的星号(*
)替换成async
,将yield
替换成await,
async
函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then
方法指定下一步的操作。进一步说,async
函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await
命令就是内部then
命令的语法糖。
2.async 函数有多种使用形式
// 函数声明 async function foo() {} // 函数表达式 const foo = async function () {}; // 对象的方法 let obj = { async foo() {} }; obj.foo().then(...) // Class 的方法 class Storage { constructor() { this.cachePromise = caches.open(‘avatars‘); } async getAvatar(name) { const cache = await this.cachePromise; return cache.match(`/avatars/${name}.jpg`); } } const storage = new Storage(); storage.getAvatar(‘jake‘).then(…); // 箭头函数 const foo = async () => {};
3.只有async
函数内部的异步操作执行完,才会执行then
方法指定的回调函数
async function getTitle(url) { let response = await fetch(url); let html = await response.text(); return html.match(/<title>([\s\S]+)<\/title>/i)[1]; } getTitle(‘https://tc39.github.io/ecma262/‘).then(console.log);
上面代码中,函数getTitle
内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行then
方法里面的console.log
。
4.按顺序完成异步操作,依次远程进行ajax请求,然后按照请求的顺序输出结果
let urls = [ ‘https://www.easy-mock.com/mock/5c73528306ffee27c6b2f0aa/testAerial/pointarr‘, ‘https://www.easy-mock.com/mock/5b62549fbf26d2748cff3cf4/dashuju/visualize‘ ]; async function loader1(urls){//所有远程操作都是继发。只有前一个 URL 返回结果,才会去读取下一个 URL for(let url of urls){ const response = await $.getJSON(url).then((res) => res); console.log(response);//ajax先后请求并返回结果 } } loader1(urls);
5.并发发出远程ajax请求,同时输出结果
let urls = [ ‘https://www.easy-mock.com/mock/5c73528306ffee27c6b2f0aa/testAerial/pointarr‘, ‘https://www.easy-mock.com/mock/5b62549fbf26d2748cff3cf4/dashuju/visualize‘ ]; async function loader(urls){//map方法的参数是async函数,但它是并发执行的,因为只有async函数内部是继发执行,外部不受影响。后面的for..of循环内部使用了await,因此实现了按顺序输出 const results = urls.map(async url => { const response = await $.getJSON(url).then((res) => res); return response; }); for(let text of results){ console.log(await text);//ajax一起请求同时返回结果 } } loader(urls);
6.异步遍历器与同步遍历器
const asyncIterable = createAsyncIterable([‘a‘, ‘b‘]); const asyncIterator = asyncIterable[Symbol.asyncIterator]();//部署异步遍历器接口 asyncIterator .next() .then(iterResult1 => { console.log(iterResult1); // { value: ‘a‘, done: false } return asyncIterator.next(); }) .then(iterResult2 => { console.log(iterResult2); // { value: ‘b‘, done: false } return asyncIterator.next(); }) .then(iterResult3 => { console.log(iterResult3); // { value: undefined, done: true } });
let arr = [‘a‘, ‘b‘, ‘c‘]; let iter = arr[Symbol.iterator]();//部署同步遍历器 iter.next() // { value: ‘a‘, done: false } iter.next() // { value: ‘b‘, done: false } iter.next() // { value: ‘c‘, done: false } iter.next() // { value: undefined, done: true }
备注:文中多数内容摘自阮一峰老师文章,仅供自我学习查阅。
原文地址:https://www.cnblogs.com/xingxingclassroom/p/10504092.html
时间: 2024-10-10 02:19:45