同步异步是前端面试中经常遇到的问题,虽然不难,但是搞清楚两者之间的关系和转换还是很重要 同步是一种线性执行的方式,执行的流程不能跨越,其后的线程要阻塞等待前面线程的运行;同步可以保证顺序一致,但是容易导致阻塞,即同步是阻塞模式。 同步一般用于流程性比较强的程序,比如用户登录功能就是同步处理的,需要用户通过用户名和密码验证后才能进入系统。 最基础的JavaScript就是同步的,单线程,自上而下运行。 通俗的话说:同步就相当于是 当客户端发送请求给服务端,在等待服务端响应的请求时,客户端不做其他的事情。当服务端做完了才返回到客户端。这样的话客户端需要一直等待,导致用户体验比较差。 异步是一种并行处理的方式,不必等待一个程序执行完,就可以执行其它的任务,即异步是非阻塞模式。在程序中异步处理的结果通常使用回调函数来处理结果。 异步可以解决阻塞问题,但是会改变顺序性。 通俗的话说:异步就是,当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间,提高了效率。 简单来说,没有异步只有同步的话,代码只能自上而下执行,若前面的代码解析时间很长,那么下面的代码就会被阻塞;而对于用户而言,阻塞就意味着”卡死”,这样就导致了很差的用户体验,这时我们就需要异步来优化代码。 promise 用同步的写法执行异步代码 Promise 优化了回调函数的用法,让原本需要纵向一层一层嵌套的回调函数实现了横向的调用,也就是链式调用 首先我们模拟一个异步时间,要求1s后输出hello world 问题来了,我们该如何输出hello world呢? 是这样吗? 不不不,这样会报错。这是因为setTimeout是异步执行,1s后才会执行 var call = “hello world”;这时会先执行return call;所以call is not defined 还是这样? 不不不,这样也达不到预期效果!这是因为执行 console.log(fn()) 时,fn()没有返回值,所以undefined;而1s后再执行setTimeout 通过回调函数,我们得到了想要的结果;但是在整体结构上,我们多了一个回调函数,这样看起来不太友好。于是,ES6的Promise诞生了! Promise是同步的,它里面执行到异步任务以前都是同步执行的。当执行的异步任务的时候,就被挂起了,然后继续执行主线程Promise后面的代码。当异步任务有结果返回的时候,Promise的状态就改变啦! Promise 构造函数接受一个函数作为参数,函数里面有两个参数 resolve 和 reject ,其中 resolve 作为执行成功的函数, reject 作为执行失败的函数 下面我们以一个小例子来讲解一下resolve和reject 多次点击按钮,上述代码会依次输出如图所示结果: 1. async 将普通方法转为 异步并且返回 promise对象 怎么拿到异步数据? async 将普通方法转为 异步并且返回 promise对象 await 必须在异步函数中使用 await 将异步代码转为同步结果,等着异步代码执行完才执行后面的代码 请仔细对比下面两个例子的输出! 同步异步的简单讲解就到这里了,若你有其它看法,欢迎指正,期待您的留言! 求学的三个条件是:多观察、多吃苦、多研究。——加菲劳
由回调函数、Promise到async/await的同步写法执行异步代码
同步
异步
为什么会有异步
ES6新特性:Promise
function fn(){ setTimeout(()=>{ var call = "hello world"; }, 1000); }
function fn(){ setTimeout(()=>{ var call = "hello world"; }, 1000); return call; } console.log(fn()); //Uncaught ReferenceError: call is not defined
function fn(){ setTimeout(()=>{ var call = "hello world"; return call; }, 1000); } console.log(fn()); //undefined
ES5:通过回调函数来处理异步执行的结果
function fn(callback){ setTimeout(()=>{ var call = "hello world"; callback(call); }, 1000); } fn(function(call){ console.log(call); //hello world });
ES6:通过Promise来处理异步执行的结果
function fn(resolve,reject){ setTimeout(()=>{ var call = "hello world"; resolve(call); }, 1000); } let p = new Promise(fn); p.then(function(res){ console.log(res); //hello world })
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <button type="button">按钮</button> <script type="text/javascript"> let oBtn = document.querySelector('button'); //定义一个开关,通过按钮来控制开关的值是true还是false let Off = true; oBtn.onclick = function(){ function fn(resolve,reject){ setTimeout(()=>{ var call = "hello world"; if(Off){ Off = !(Off); resolve(call); }else{ Off = !(Off); reject('获取失败!'); } }, 1000); } let p = new Promise(fn); p.then((res) => { console.log(res);//hello world },(res) => { console.log(res);//获取失败! }) } </script> </body> </html>
ES7新特性:async…await
2. await 将异步代码转为同步结果,等着异步代码执行完才执行后面的代码方法一:
//async 将普通方法转为 异步并且返回 promise对象 async function test(){ return 'goods'; } console.log(test());//Promise {<resolved>: "goods"} let p = test(); p.then(function(res){ console.log(res); //goods })
方法二:
async function test(){ return 'goods'; } //await 必须在异步函数中使用 async function fn(){ let data = await test(); console.log(data); //goods } fn();
async function fn1(){ return '成功'; } async function fn2(){ console.log(1111); let p = fn1(); p.then(function(res){ console.log(res); }); console.log(3333); } fn2(); /** 输出: 1111 3333 成功 */
async function fn1(){ return '成功'; } async function fn2(){ console.log(1111); // await 将异步代码转为同步结果,等着异步代码执行完才执行后面的代码 let data = await fn1(); console.log(data); console.log(3333); } fn2(); /** 输出: 1111 成功 3333 */
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算