同步 异步 异步请求在江湖中的地位非常重要,异步给JS带来了更多的可能,我们是不是遇到过这样的业务场景:后一个请求依赖前一个请求的结果,也就是一个请求依赖另一个请求,如果依赖层数再多一点,很容易出现回调地狱的现象。本文将介绍几种异步请求的处理方式,拭目以待。 知乎推荐回答:你去商场买衣服,刚好你的 size 没有了,于是你把电话留给了店员,过几天,那件衣服补货了,店员给你打电话,你去店里把它买下来。在这个例子里,你的电话号码就是回调函数,你把电话留下叫做登记回调函数,店里补货了这个事件触发了回调函数,店员给你打电话是调用回调函数,你去店里买下来是响应回调事件。 回调函数就是 任何一个 被以该回调函数为其参数的其他方法调用的方法。 以上代码用来实现异步操作,没有什么问题,但如果业务不只是这两个文件,那还要很多个回调函数的嵌套吗?这样的代码可维护性,可读性都变得很差,这就是回调地狱。 Promise对象,返回一个“异步承诺”,不管是请求成功还是出错都会执行,promise 对象带有 resolve 和 reject 方法,可以请求结果进行分开处理。promise对象有三种状态: promise的一个便利是,针对多个异步请求的情况,可以使用 Promise.all 方法来确保各个请求的执行返回,避免了“回调地狱”。
pending 状态可以转换为 fulfilled 或者 rejected ,并且只能转换一次,如果 pending 转化为其中一种状态,就不能转换为另一种状态了,并且 fulfilled 和 rejected 状态只能由 pending 转化而来,两者之间不能互相转换。 promise 可以做更多事情,比如,有若干异步任务,需要先做任务1,成功后做任务2,任何任务失败则不再继续并进行错误处理,要实现这样的异步任务,如果不用 Promise对象,需要一层一层的嵌套回调。有了 Promise ,我们只需要简单的写 then 方法可以被同一个 promise 调用多次,返回一个新的 promise 对象,因此可以通过链式调用 then 方法,避免了地狱回调的嵌套回调。 试想一个页面聊天系统,需要从两个不同的URL获取用户的个人信息和好友列表,这两个任务是可以并行执行的,用 Promise.all() 实现如下。 有些时候,同时发起两个请求获取信息,只需要获取先返回的数据即可,这种情况下,用 Promise.race()实现。 可能 p1 执行较快,promise 的 then() 将获得结果 p1,p2 仍在继续执行,但执行结果将被丢弃。 总结: 将上面例子做下修改,加深对这两者的理解: 虽然promise 很便利了,但在代码简洁方面,还有待优化,因此由了 async/await ,在多个请求情况下更是可以“链式”声明,可以大大节省代码量。 Async/Await 是什么? async本意是异步,而 await 可以认为是 async wait 的缩写,所以可以理解为:async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。 另外,语法规定,await 只能出现在 async 函数中。 async起什么作用? async 函数是如何处理它的返回值的?我们写一个 demo 测试一下 async 函数返回的是一个 promise 对象,如果在函数中 return ,async 会通过 Promise.resolve() 封装成 Promise 对象。但如果 不 return ,会出现什么情况,很显然,它会返回 :Promise.resolve(undefined) Promise 的特点是:无等待,所以在没有 await 的情况下执行 async 函数,会立即执行,返回一个 promise 对象,绝不会阻塞后面的语句,这和普通的 promise 对象函数没啥区别,关键在于 await 做了什么? await 在等待一个 async 函数完成,因为 async 函数返回一个 Promise 对象,所以 await 可以用于等待一个 async 函数的返回值,如果 await 等到了要等的东西,比如说是一个 promise 对象,await 会阻塞后面的代码,等待 promise 对象 resolve ,然后得到 resolve 的值,作为 await 表达式的运算结果。文章目录
前言
javascript 语言执行环境是单线程,就是一次只能完成一个任务,如果同时有多个任务,必须排队执行。这种模式的好处是实现较简单,执行环境单纯,缺点是只要有一个任务耗时长,后面的任务必须排队,拖延整个程序的执行效率。
同步 & 异步
回调地狱
大家在学习 Jquery 的时候都应该接触过回调函数,在这,再次总结一下到底什么是回调函数?
//callback //读./pakage.json的内容,写入./p.json文件,读取成功 2s后打印"ok" const fs = require('fs') fs.readFile('./pakage.json',(err,info) => { fs.writeFile('./p.json',info,(err) => { if(!err) { setTimeout(() => { console.log('ok') },2000) } }) })
Promise对象
<script src="https://cdn.bootcss.com/bluebird/3.5.1/bluebird.min.js"></script>//如果低版本浏览器不支持Promise,通过cdn这种方式 <script type="text/javascript"> function loadImg(src) { var promise = new Promise(function (resolve, reject) { var img = document.createElement('img') img.onload = function () { resolve(img) } img.onerror = function () { reject('图片加载失败') } img.src = src }) return promise } var src = 'https://www.imooc.com/static/img/index/logo_new.png' var result = loadImg(src) result.then(function (img) { console.log(1, img.width) return img }, function () { console.log('error 1') }).then(function (img) { console.log(2, img.height) }) </script>
promise 多个串联操作
job1.then(job2).then(job3).catch(handleError);
promise 常用方法
promise.all()
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); // 同时执行p1和p2,并在它们都完成后执行then: Promise.all([p1, p2]).then(function (results) { console.log(results); // 获得一个Array: ['P1', 'P2'] });
promise.race()
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); Promise.race([p1, p2]).then(function (result) { console.log(result); // 'P1' });
var src1 = 'https://www.imooc.com/static/img/index/logo_new.png' var result1 = loadImg(src1) var src2 = 'https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg' var result2 = loadImg(src2) Promise.all([result1, result2]).then(function (datas) { console.log('all', datas[0])//<img src="https://www.imooc.com/static/img/index/logo_new.png"> console.log('all', datas[1])//<img src="https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg"> }) Promise.race([result1, result2]).then(function (data) { console.log('race', data)//<img src="https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg"> })
Async/Await
async function testAsync() { return "hello async"; } const result = testAsync(); console.log(result);//Promise { 'hello async' }
var step1 = async function () { return new Promise(function (resolve, reject) { let st = setTimeout(() => { resolve('step1'); }, 1000); }); } var step2 = function () { return new Promise(function (resolve, reject) { let st = setTimeout(() => { resolve('step2') }, 1000); }); } var step3 = function () { return new Promise(function (resolve, reject) { let st = setTimeout(() => { resolve('step3') }, 1000); }) } async function test() { var data1 = await step1(); console.log(data1); var data2 = await step2(); console.log(data2); var data3 = await step3(); console.log(data3) } test();
最后
以上就是对js中异步处理几种方式的简单理解,理解异步,有助于对代码的进一步理解。 本文仅作为笔者个人学习记录,能力有限,如有错误,请指正。不胜感激~~~
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算