声明,只是简单地提了提promise的基本使用,大牛绕道^_^
你须要知道1.axios是个库
2.axios()返回一个Promise实例
3.你能够把axios()理解为$.ajax(),它们功能相近,只不过axios遵循promise规范
ios
axios({ url: '.' }).then((resolve) => { console.log(resolve) return '我是第二个then' }, (reject) => { console.log(reject) }).then((resolve_2) => { console.log(resolve_2) // '我是第二个then' }, (reject_2) => { console.log(reject_2) })
为了防止你对这个链式调用
看得眼花缭乱,我把这个给简化一下ajax
axios({ url: '.' }).then(成功回调, 失败回调) .then(成功回调2, 失败回调2)
ok,准备好了吗?下面咱们先来了解Promise的一些基本概念编程
Promise是专门用来解决异步编程问题的,避免了层层嵌套的回调函数[Callback Hell]
下面是一个用传统方法Callback Hell来写的异步代码
能够很是明显地看出来,Callback Hell的方式让代码的可读性变得很是差axios
function loadImg(src, callback, fail) { let img = new Image() img.onload = function () { // 成功回调 callback(img) } img.onerror = fail // 失败回调 img.src = src } let src = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' loadImg(src, function (img) { console.log(img.width) }, function () { console.log('error') })
pending
初始态,既不成功也不失败fulfilled
异步操做成功rejected
异步操做失败Promise对象表明一个异步操做,且只有异步操做的结果,能够决定当前是哪种状态
,任何其余操做都没法改变这个状态,peding可转化为fulfilled与rejected,但fulfilled与rejected不可相互转化
promise
那知道这三个状态又有什么用咧?
OK,咱们看下面的代码浏览器
axios({ url: '.' }).then(成功回调, 失败回调)
axios({url: '.'})
异步操做成功表明了pending
-> fulfilled
-> then里的第一个参数
【成功回调】
异步操做失败表明了pending
-> rejected
-> then里的第二个参数
【失败回调】异步
由于 Promise.prototype.then
和 Promise.prototype.catch
方法返回promise 对象
因此它们能够被链式调用。异步编程
OK,下面让咱们仔细看一下回调触发机制究竟怎样的过程函数
axios({ url: '.' }).then(成功回调, 失败回调) .then(成功回调2, 失败回调2)
是否是看的有点晕?不要紧,下面我来详细解释一下
1.异步操做成功
-> 进入第一个then的成功回调
-> 成功回调
执行异步操做成功 -> 因为又返回了一个Promise实例,其状态因为异步操做成功,由pending
转为了fullfiled
,因此还能够再调用第二个then -> 进入第二个then的成功回调2
2.异步操做失败
-> 进入第一个then的失败回调
-> 失败回调
执行异步操做成功 -> 因为又返回了一个Promise实例,其状态因为异步操做成功,由pending
转为了fullfiled
,因此还能够再调用第二个then -> 进入第二个then的成功回调2
测试
你的问题:
1.为何第一个then不论调用成功回调
仍是失败回调
,第二个then都会调用成功回调2
呢
答:由于第二个then调用进入哪一个回调函数,彻底是看第一个then返回的Promise是什么状态,换言之 —— 看异步操做成功与否
举一个栗子
axios({ url: '.' }).then((resolve) => { return xxx // 注意xxx是个未声明的变量 // 浏览器会报错,说明异步操做失败了 // 因此第一个then返回的Promise的状态是 rejected }, (reject) => {}) .then((resolve_2) => { console.log(1) }, (reject_2) => { // 因此第二个then只会调用它的第二个参数 console.log(2) })
2.你咋不提catch咧?
由于catch就是then的一个语法糖呀
catch等价于then只有第二个参数【失败回调】的形式
上面的例子用catch,能够这么写
axios({ url: '.' }).then((fulfilled) => { return xxx // 注意xxx是个未声明的变量 // 因此第一个then返回的Promise的状态是 rejected }, (rejected) => { }).catch((rejected) => { // 因此直接进入catch console.log(2) })
第一步
// 声明一个函数 让这个函数返回一个Promise实例 let setPromise = function () { return new Promise() }
第二步
// new Promise()接受一个函数 // 规定这个函数必需要有两个参数【成功回调,失败回调】 let a = 0 let setPromise = function () { let fn = (x, y) => { setTimeout(() => { x('success') // 必定要写上异步操做成功后,会调用的回调函数 }, 2000) } return new Promise(fn) // 在new的过程当中必定有一句fn.call(undefined, fulfilled, rejected) }
第三步
// 写的更装逼点,顺别把x,y换个名字【实际上是规定】 let setPromise = function () { return new Promise((resolve, reject) => { setTimeout(() => { resolve('success') }, 2000) }) // 在new的过程当中必定有一句fn.call(undefined, fulfilled, rejected) }
第四步
// 你要作什么,就用then输入到这个Promise实例里面去 let promiseInstance = setPromise() promiseInstance.then((success) => { console.log(success) // 'success' }, () => { console.log('失败啦') })
总结
let setPromise = function () { return new Promise((resolve, reject) => { // 你的异步代码 setTimeout(() => { resolve('success') // 给成功回调resolve传递一个参数 'success' console.log('测试一下') // 两秒以后被执行 }, 2000) }) } // 你要作什么,就用then输入到这个Promise实例里面去 let promiseInstance = setPromise() promiseInstance.then((resolve) => { // 异步操做执行成功后执行 console.log(resolve) // 'success' console.log('完美运行') // '完美运行' }, () => { console.log('失败啦') })
其实对于Promise和then有一个更具象化的理解
Promise的中文翻译是承诺
,then的中文翻译是而后
因此,你能够想象你去买橘子,结果店里没有进货,店员对你Promise
,只要他店里到货,then
他就会通知你