回调函数、Promise、Generator 函数和async函数
看了几篇文章,受益匪浅,写几个demo看下理解是否正确:
文章链接:Generator 函数的含义与用法 - 阮一峰的网络日志 (ruanyifeng.com) async 函数的含义和用法 - 阮一峰的网络日志 (ruanyifeng.com)
回调函数
<script> //----------------------------回调函数---------------------------- function getFile(url, myCallback) { let req = new XMLHttpRequest(); req.open("GET", url); req.onload = function () { if (req.status == 200) { myCallback(req.responseText); } else { myCallback("Error: " + req.status); } }; req.send(); } //错误url 404 getFile("../for-test.html", (res) => { console.log(res); //Error: 404 }); //正确url getFile("../../for-test.html", (res) => { console.log(res); //test }); </script>
多重请求导致的“回调地狱”
<script> //----------------------------回调函数---------------------------- function getFile(url, myCallback) { let req = new XMLHttpRequest(); req.open("GET", url); req.onload = function () { if (req.status == 200) { myCallback(req.responseText); } else { myCallback("Error: " + req.status); } }; req.send(); } //----------------------------多重请求时出现的多重回调函数嵌套('回调地狱')---------------------------- getFile("../../for-test.html", (res) => { console.log(res); //test getFile("../for-test.html", (res) => { console.log(res); //Error: 404 }); }); </script>
Promise
<script> //----------------------------Promise---------------------------- //为了解决多重请求时出现的多重回调函数嵌套('回调地狱') function getFilePromise(url) { let myPromise = new Promise((myResolve, myReject) => { let req = new XMLHttpRequest(); req.open("GET", url); req.onload = function () { if (req.status == 200) { myResolve(req.response); } else { myReject("Error: " + req.status); } }; req.send(); }); return myPromise; } getFilePromise("../../for-test.html") .then((value) => { console.log(value); }) .then(() => { return getFilePromise("../for-test.html"); }) .then((value) => { console.log(value); }) .catch(function (error) { console.log(error); }); </script>
Generator 函数
<script> //----------------------------Generator 函数---------------------------- //"协程"(coroutine),意思是多个线程互相协作,完成异步任务。 // 协程A开始执行,协程A执行遇到异步任务,进入暂停,执行权转移到协程B。协程B完成异步任务交还执行权给协程A。协程A恢复执行。 // Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。使用function* funcname 和yield定义 function* getFileGen(url) { try { let result = yield fetch(url); } catch (error) { //捕获函数体外抛出的错误 console.log(error); } return result; } // 调用 Generator 函数,会返回一个内部指针(即遍历器 )g,调用指针 g 的 next 方法,会移动内部指针 // next 方法的作用是分阶段执行 Generator 函数。每次调用 next 方法,会返回一个对象,表示当前阶段的信息( value 属性和 done 属性)。 // value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。 var g = getFileGen("../../for-test.html"); var result = g.next(); console.log(result); //{value: Promise, done: false} result.value .then(function (data) { return data.text(); }) .then(function (data) { console.log(data); //test console.log(g.next()); //{value: undefined, done: true} }); //抛出错误 g.throw("出错了"); //产生的问题:流程管理(即何时执行g.next()) </script>
async函数
<script> //----------------------------async 函数---------------------------- //async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法。 //async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。await关键字只在async函数内有效,如果在async函数体之外使用它,会抛出语法错误。 // async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。 async function test() { return "hello"; } test() .then((res) => { console.log(res); }) .catch((error) => { console.log(error); }); async function test1() { return new Promise(function (resolve, reject) { if (true) { resolve("hello"); } else { reject("error"); } }); } test1() .then((res) => { console.log(res); }) .catch((error) => { console.log(error); }); //await关键字可以跟在任意变量或者表达式之前,但通常await后面会跟一个异步过程。await使用时,会阻塞后续代码执行。 async function test2() { var result = await fetch("../../for-test.html") .then((response) => response.text()) .catch((err) => console.log("Request Failed", err)); var result1 = await "test2"; console.log(result); console.log(result1); } test2(); </script>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix