promise 和 async/await
这两者都是异步解决方案,比callback要慢很多。但使用方便,被越来越多api支持,还是要学习了。
promise
callback 是函数,调用者调用cb的过程是函数调用,被调用的cb函数必须预先传递进去,所以:写法上有违直觉(后执行的要先写好),还会造成多层回调嵌套
解决办法promise,这是一个对象,可以保存 调用者 的执行状态和结果,所以被调用的cb可以后传递进去,由promise对象调用,同理,这个被调用者也可以继续把结果委托给promise对象,也解决的嵌套的问题。
注意的是,调用者是函数,promise仍然要预先传递过去,所以promise用法是:
let agent = new Promise((resolve,reject)=>{ // 真实的调用者在这里, ⚠️这个函数是立即执行的。假设执行结果是result // 把结果委托给resolve: resolve(result) }) agent.then((result)=>{ // 被调用的cb在这里 // 如果继续返回 Promise return new Promise(()=>{}) }).then(()=>{ // 这里也可以继续被调用的cb })
写法上,因为有了委托函数resolve,所以真正的回调可以写在后面,并且解决的嵌套的问题
调用者函数是立即执行的,后续代码也会继续执行(并行)
但由于js的事件队列的单线程模式,
后续代码执行是排在 调用者函数后面的,
resolve也是把cb添加到事件队列中
创建自己的Promise的方法:
把调用者函数放到Promise里面,
把传递给回调的结果传递给resolve
把回调cb写在then函数里。
await/async
await 是接受promise成功函数结果的另外一种方法
promise/resolve把结果(应该执行并传给then获得的函数),传给await,并赋值给await前面的变量
但这里的await 是会暂停后续代码执行的(跟上面提到的promise模式不相同)
所以,调用await 的函数要 要加上 async ,通知js引擎注意执行方式。
function agent(){ return new Promise(()=>{ // 调用者 }) // 注意,不添加 then } async function f(){ let r = await agent(); // 回调cb 放这里 cb(r); }
要注意的是 async 是把函数转变成一个 promise对象,所以 他也有上述两种方法获得结果。
这里可能会形成一个 async / await async / await 的嵌套地狱,
所以这个机制,只能保证 async函数内是阻塞执行,而async 外(整个js)执行依然是非阻塞的
参考资料:
promise
廖雪峰的入门课程
https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544
简单解释过程
https://www.jianshu.com/p/1b63a13c2701
阮一峰的教程,比较全面
https://es6.ruanyifeng.com/#docs/promise
提到一些使用中的技巧和错误,不错
http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/
未看,有一些例子
https://juejin.im/post/5bcedb78e51d457b7d135746
赤裸裸的题目
http://www.fly63.com/article/detial/87
https://www.lizenghai.com/archives/39490.html
async/await
async和await
执行过程的理解
https://www.jianshu.com/p/b4fd76c61dc9
解释了本质,不错
https://segmentfault.com/a/1190000007535316