Promise
是一种异步编程的解决方案
基本使用
使用 new Promise
创建一个 Promise 实例,需要传入一个函数为参数,函数默认会传入 resolve 和 reject 两个函数。当调用了 resolve 函数后会自动调用 then 函数
new Promise((resolve, reject) => {
// 第一次网络请求的代码
setTimeout(() => {
resolve()
}, 1000)
}).then(() => {
// 第一次拿到结果的处理代码
console.log('Hello World!');
return new Promise((resolve, reject) => {
// 第二次网络请求的代码
setTimeout(() => {
resolve()
}, 1000)
}).then(() => {
// 第二次拿到结果的处理代码
console.log('Hello Vuejs');
return new Promise((resolve, reject) => {
// 第三次网络请求的代码
setTimeout(() => {
resolve()
}, 1000)
}).then(() => {
// 第三次拿到结果的处理代码
console.log('Hello Python');
})
})
})
当往 resolve 中传入参数时,参数会传到 then 函数中,当往 reject 中传入参数时,参数会传到 catch 函数中
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data);
reject('error message');
})
}).then((data) => {
// 用来处理成功代码
console.log(data);
}).catch(err => {
// 用来处理失败代码
console.log(err);
})
其他方式
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello Vuejs');
reject('error message');
}, 1000)
// then 传入了两个参数
}).then(data => {
console.log(data);
}, err => {
console.log(err);
})
三种状态
异步操作之后会有三种状态
- pending:等待状态,比如正在进行网络请求,或者定时器没有到时间
- fulfilled:满足状态,当我们主动回调了 resolve 时,就处于该状态,并且会回调 then()
- rejected:拒绝状态,当我们主动回调了 reject 时,就处于该状态,并且会回调 catch()
简写方式
普通的写法
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa');
}, 1000);
}).then(res => {
console.log(res, '第一层的10行处理代码');
return new Promise((resolve) => {
resolve(res + '111');
}).then(res => {
console.log(res, '第二层的10行处理代码');
return new Promise((resolve) => {
resolve(res + '222');
}).then(res => {
console.log(res, '第三层的10行处理代码');
})
})
})
简写之后
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa');
}, 1000);
}).then(res => {
console.log(res, '第一层的10行处理代码');
// 两样也能 Promise.reject('error message)
return Promise.resolve(res + '111')
}).then(res => {
console.log(res, '第二层的10行处理代码');
return Promise.resolve(res + '222')
}).then(res => {
console.log(res, '第三层的10行处理代码');
})
再次简写
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa');
}, 1000);
}).then(res => {
console.log(res, '第一层的10行处理代码');
return res + '111'
}).then(res => {
console.log(res, '第二层的10行处理代码');
return res + '222'
}).then(res => {
console.log(res, '第三层的10行处理代码');
})
throw
捕获错误的另一种写法
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa');
}, 1000);
}).then(res => {
console.log(res, '第一层的10行处理代码');
throw 'error message'
}).then(res => {
console.log(res, '第二层的10行处理代码');
return res + '222'
}).then(res => {
console.log(res, '第三层的10行处理代码');
}).catch(err => {
console.log(err);
})
all 方法
当要同时获取两个异步请求结果才能进行下一步时,可以使用 all 方法
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result1')
}, 2000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result2')
}, 1000)
})
]).then(results => {
console.log(results);
})
打印结果:
axios
支持多种请求方式
- axios(fonfig)
- axios.request(config)
- axios.get(url, config)
- axios.delete(url, config)
- axios.head(url, config)
- axios.post(url[,data[,config]])
- axios.put(url[,data[,config]])
- axios.patch(url[,data[,config]])
安装和使用
安装
npm install axios —save
使用
import axios from 'axios'
axios({
url: 'http://123.207.32.32:8000/home/multidata',
// 默认为 get 请求
method: 'get'
}).then(res => {
console.log(res);
})
axios({
// http://123.207.32.32:8000/home/data?type="pop"&page=1
url: 'http://123.207.32.32:8000/home/data',
// get 请求参数拼接
params: {
type: 'pop',
page: 1
},
method: 'get'
}).then(res => {
console.log(res);
})
post 请求 params 要换成 dta
并发请求
axios.all([
axios({
url: 'http://123.207.32.32:8000/home/multidata',
}),
axios({
url: 'http://123.207.32.32:8000/home/data',
params: {
type: 'sell',
page: 5
}
})
]).then(results => {
console.log(results);
})
// results 拿到的是一个数组,这样很不方便,还有另一种写法
.then(axios.spread((res1,res2) => {
console.log(res1);
console.log(res2);
}))
数组的解构
ES6 中的语法
const names = ['why', 'kobe', 'james']
const [name1, name2, name3] = names
全局配置
常见的配置选项可见文档
// axios 的配置都能够提取出来
axios.defaults.baseURL = 'http://123.207.32.32:8000'
axios.defaults.timeout = 5000
// 并发请求
axios.all([
axios({
url: '/home/multidata',
}),
axios({
url: '/home/data',
params: {
type: 'sell',
page: 5
}
})
]).then(results => {
console.log(results);
})
axios 实例
当数据需要向多个服务器获取时,全局配置显示不能满足需求
// 创建对应的 axios 的实例
const instance1 = axios.create({
baseURL: 'http://123.207.32.32:8000',
timeout: 5000
})
// 每一个实例都有自己的配置
const instance2 = axios.create({
baseURL: 'http://222.111.33.33:8000',
timeout: 5000
})
instance1({
url: '/home/multidata'
}).then(res => {
console.log(res);
})
instance2({
url: '/home/data',
params: {
type: 'sell',
page: 5
}
}).then(res => {
console.log(res);
})
axios 封装
封装
// src/network/request.js
import axios from 'axios';
// 不使用 export default 因为可能会封闭多个实例
export function request(config) {
// 1.创建 axios 实例
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000',
timeout: 50000
})
// instance 返回的是一个 promise
return instance(config)
}
使用
import { request } from "./network/request"
request({
url: '/home/multidata'
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
拦截器
用于我们在发送请求或者得到相应结果后,进行对应的处理
请求拦截器
**
拦截到的是的相关的配置信息
instance.interceptors.request.use(config => {
console.log(config);
// 如果不返回出去,发送请求时将没有 config
return config
}, err => {
console.log(err);
})
响应拦截器
拦截到的是响应的结果
instance.interceptors.response.use(res => {
console.log(res);
// 如果不返回出去,就接收不到响应的结果
return res
}, err => {
console.log(err);
})
better-scroll
安装和使用
安装
npm install better-scroll —save
使用
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- 这里可以放一些其它的 DOM,但不会影响滚动 -->
</div>
import BScroll from '@better-scroll/core'
let bs = new BScroll('.wrapper')
侦测滚动条
import BScroll from '@better-scroll/core'
let scroll = new BScroll('.wrapper', {
// 0,1老师不侦测实时的位置
// 2:在手指滚动的过程中侦测,手指离开后的惯性滚动过程中不侦测
// 3:只要是滚动,都侦测
probeType: 3
})
// 监听事件
scroll.on('scroll', (pos) => {
console.log(`Now position is x: ${pos.x}, y: ${pos.y}`)
})
click
BetterScroll 默认会阻止浏览器的原生 click 事件。
const bs = new BetterScroll('.wrapper', {
click: true
})
pullUpLoad
触发时机:当底部下拉距离超过阈值(上拉加载更多)
import BetterScroll from '@better-scroll/core'
const bs = new BetterScroll('.wrapper', {
pullUpLoad: true
})
bs.on('pullingUp', () => {
console.log("上拉加载更多")
// 当触发了一次该事件后将不会再次触发,必须清除事件
bs.finishPullUp()
})
滚动原理
better-scroll 会计算出 wrapper 的高度,再计算出内容的高度,从而得出可滚动的范围。
而且商城项目中,首页的图片是异步加载的,当图片加载完之前 better-scroll 就已经把可滚动的范围计算好了
事件总线
响应式原理
const obj = {
message: "哈哈哈",
name: "why"
}
Object.keys(obj).forEach(item => {
let value = obj[key]
Object.defineProperty(obj, key, {
set(newValue) {
console.log("监听" + key + "改变");
value = newValue;
},
get() {
return value
}
})
})