传统方式—将回调函数作为函数参数
传统的将回调函数直接作为函数参数的异步调用的形式
// 异步调用将回调函数作为参数的形式
$.get('/', function(data){console.log(data.length)}
// $.get 是一个函数,里面的第二个参数又是一个函数,这个函数作为一个回调函数,将数据拿到,拿到之后,打印出来
Promise
promise则用的是then的方式来拿去数据
如:浏览器中的fetch,返回结果就是一个promise
看这个promise怎么拿到这个异步调用的结果数据
通过.then方法,then方法将返回值转成一个文本,将这个文本长度打印出来
// 将回调函数放到promise中的then方法中
fetch('/').then(res=>res.text()).then(data=>console.log(data.length))
Promise和传统方式的区别 / 转化方式
例如:
setTimeout也是一个典型的回调函数作为参数的形式
我们可以将一个回调函数作为参数的形式改造成一个promise .then的形式
setTimeout(function(){console.log(123)},1000)
// 用promise进行改造
// promise是有构造函数的
// 直接new一个promise
// 构造函数接的参数是一个resolve和rejec;用resolve去接数据,接的是then里面需要的返回值
// 当new promise的时候,里面的内容/函数就会立即被执行;所以需要在后面直接跟then;因而为了能实现调用时执行,Promise一般都是作为函数的返回值
new Promise((resolve, reject)=>{
setTimeout(function(){resolve(123)},1000)
}).then(res=>console.log(res))
// resolve接收正确结果,导入then中,reject接收错误,导入到catch中
// 当使用reject接收的时候,需要通过catch去获取值
new Promise((resolve, reject)=>{
setTimeout(function(){reject(123)}, 1000)
}).then(res=>console.log(res)).catch(e=>console.log(e))
通过resolve .then接收正确的数据
通过reject .catch接收错误
async / await
当async修饰函数后,函数内可以使用await
var p1 = () => new Promise((res, rej)=>setTimeout(()=>res(12345), 1000)
// async是用来修饰一个函数
async function q1(){
// p1 自己运行完返回的是一个promise,前面加了await,返回的就是p1运行的结果,那么res拿到的就是12345
var res = await p1()
console.log(res)
}
q1() // 12345
// 这种方式和上面的async基本等价,使用async可以同步编程去整理代码逻辑,避免了.then又.then的回调地狱
// async + await 是promise + then 的语法糖,可以很好的避免回调地狱
function q1() {
p1().then(res=>console.log(res))
}
q1() // 12345
回调嵌套 / 回调地狱
首先执行sql1,看是否有错误,如果有错误,打印错误;
如果没有错误,拿data中的数据拼成sql2,然后拿data2中的数据拼成sql3,最后打印data3
多次回调嵌套,代码看起来很繁琐
使用async...await,可以很好的解决回调嵌套
首先执行sql1,得到data1,
data1拼成sql2,得到data2,
data2拼成sql3,得到data3
最后的data3就是我们要的数据
await拿的是resolve的数据或者说传给then的数据
reject的需要靠try…catch
如果在执行sql1的时候报错了,那我们就拿不到数据了,会得到一个异常,如何去获取这个异常:通过try…catch,可以统一的对这个异常做一个try…catch
小脑筋:.then在调用链中的秘密
版权声明:本文为guairena原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。