摘要:异步编程一般用来调取接口拉数据。通过我描述的篇幅,就知道异步编程比同步编程麻烦许多。远古时期,异步编程是通过回调函数来解决的。
半理解系列--Promise的进化史
学过js的都知道,程序有同步编程和异步编程之分,同步就好比流水线,一步一个脚印,做完上个任务才做下一个,异步编程好比客服,客服接了一个电话,收到了一个任务,然后把任务交给另外的人来处理,同时,继续接听下一个电话,等到另外的人处理完任务了,再通知客服,客服再反馈给第一个打电话的人。异步编程一般用来调取接口拉数据。
通过我描述的篇幅,就知道异步编程比同步编程麻烦许多。远古时期,异步编程是通过回调函数来解决的。但是回调函数会有回调地狱的问题,回调的多了,维护人员看起来头都大了,好比:taskC需要等待taskB做完(taskC才执行),taskB又需要等待taskA做完(taskB才执行)
function taskA (cb) { //..do task A cb() } function taskB(cb){ //..do task B cb() } function taskC(cb){ //..do task C cb() } taskA(function(){ taskB(function(){ taskC() }) }) ...以此类推,不断循环嵌套,最终陷入地狱
而Promise就把这一系列的回调,通过链式调用的方式连接起来,看起来清爽多了。同样是上面的代码,Promise可以这么写(伪代码)
new Promise().then(taskA).then(taskB).then(taskC)promise的使用
const promise = new Promise((resolve,reject)=>{ if (/*do something done*/){ resolve() // 可在此传参数 } else { // do something fail reject() // 可在此传参数 } }) promise.then(()=>{ //do something }).catch(e => { throw e})
上面的resolve,可以当作task函数的cb回调函数,当resolve()执行的时候,then方法中的回调会被执行,如果是reject执行,错误会被catch捕捉。
Promise的静态方法
上面说的then和catch都是Promise的原型方法,即Promise.prototype.then/catch
Promise本身有两个静态方法,其作用类似 new Promise()
Promise.resolve()
const promise1 = Promise.resolve() 等价于 const promise2 = new Promise((reslove)=>{ reslove() })
使用该方法调用then方法
Promise.reject()
const promise1 = Promise.reject() 等价于 const promise2 = new Promise((resolve,reject)=>{ reject() })
使用该方法会被catch捕捉
Promise的链式调用
Promise的实例对象的then方法是可以重复调用的,then方法返回的是一个promise实例对象,所以可以重复调用then方法,并且(敲黑板),上一个then方法的返回值,会作为下一个then方法的参数传递
举个栗子:
const promise = Promise.resolve("start") promise.then((params)=>{ console.log(params) // start return "aa" }).then((params) => { console.log(params) // aa return "bb" }).then((params)=>{ console.log(params) // bb return "cc" }) // 最后会返回一个状态是resolve(cc)的promise对象:Promise {: "cc"}
深入一下(又不会怀孕)
function badAsyncCall() { var promise = Promise.resolve(); promise.then(function() { // 任意处理 return "newVar"; }); return promise; } // 修改一下 function goodAsyncCall() { var promise = Promise.resolve(); return promise.then(function() { // 任意处理 return "newWar"; }); }
以上两个写法是不是很相似,唯一不同的就是return的处理。但调用,badAsynccall会出错,而anAsyncCall能正确执行,比如:
badAsyncCall().then(params => { console.log("bad--",params)}) // bad-- undefined goodAsyncCall().then(params => { console.log("good--",params)}) // good-- newWar
分析:第一种,错误写法,首先在 promise.then 中产生的异常不会被外部捕获,此外,也不能得到 then 的返回值,即使其有返回值。
原因:由于每次 promise.then 调用都会返回一个新创建的promise对象,第一种返回的promise,相当于没有调用过函数内部的then方法,是一个全新的promise实例对象
结论: 统一使用promise链式调用,如:promise.then(taskA).then(taskB)
### async&await和promise的前世缘缘
promise说白了还是用回调的方式来解决异步问题,跟真正同步还是有差距的。
异步编程的最高境界,就是根本不用关心它是不是异步!(来之ruanyifeng老师的话)
所以,async&await方案出现了
用法:
function readFile(fileName) { return new Promise((resolve,reject)=>{ fs.readFile(fileName, function(error, data) { if (error) return reject(error); resolve(data); // 向thenc传送异步读取文件的数据 }); }) } // 调用 readFile(fileName).then(function(data){ console.log("prmoise read files data --", data) }) // 等价于 async function asyncFn(fileName){ const data = await readFile(fileName) console.log("await data --", data) return data } asyncFn(fileName)
写法是不是简洁了许多!
其实async就是一个Promise的语法糖,它的返回值是一个promise对象,因此可以用then方法做链式调用(但参数就是async函数中的返回值,如上文的data!!)
async函数中还可以不使用promise,比如:
async function asyncFn(){ const data = await setTimeout(function(){ console.log("setTimeout") return "data" },1000) console.log("data",data) // Timeout {} 对象 } console.log("async",asyncFn()) // Promise {}
但这两者,其实经常混用,常见的就是readFile函数的做法啦
看懂以上的,才大家出一道题看看能不能懂;
async function asynFn(){ await Promise.resolve("aaa") const data = { b:"bb", c:function(){ return this.b } } return data //return 作为参数传递给then then的chain链也是通过return参数来不断传递给后面的then } var cball = asynFn() cball.then(function(data){ console.log("data:",data) })
还有一种异步编程的语法糖: * & yield
跟async基本一样,不在本文讨论的重点。有兴趣自行google啦
参考资料:
async 函数的含义和用法
Promise 对象
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/107430.html
摘要:签订协议的两方分别是异步接口和。在异步函数中,使用异常捕获的方案,代替了的异常捕获的方案。需要注意的是,在异步函数中使异步函数用时要使用,不然异步函会被同步执行。 同步与异步 通常,代码是由上往下依次执行的。如果有多个任务,就必需排队,前一个任务完成,后一个任务才会执行。这种执行模式称之为: 同步(synchronous) 。新手容易把计算机用语中的同步,和日常用语中的同步弄混淆。如,...
摘要:截至目前,人类大脑是已知宇宙中最复杂的物体。但是天河二号也是一个庞大的家伙,它占地平方米,使用兆瓦的电力大脑只需瓦,耗资亿美元建造。建议,通过查看可以以,美元购买多少来考虑计算机的状态。 showImg(http://upload-images.jianshu.io/upload_images/13825820-c158f685feaf8ae6.jpg?imageMogr2/auto-...
阅读 1401·2021-11-15 11:38
阅读 3535·2021-11-09 09:47
阅读 1950·2021-09-27 13:36
阅读 3188·2021-09-22 15:17
阅读 2525·2021-09-13 10:27
阅读 2843·2019-08-30 15:44
阅读 1136·2019-08-27 10:53
阅读 2683·2019-08-26 14:00