1.用途:Promise()是一个构造函数,用于解决回调地狱(异步依赖异步回调)
2.属性:Promise有两个属性:state(pending,fulfilled,rejected)和result
3.方法:.then .catch
// 4.语法
const p = new Promise((resolve, reject) => {
resolve("请求成功时的结果")//是一个函数,用于改变promise的state,改为成fulfilled
// reject("请求失败时的结果")//是一个函数,用于改变promise的state,改为失败reject
//这种状态的改变是一次性的(同一个实例只能调用resolve或reject其中一个一次)
})
//用then接收请求的结果,用法:接收两个函数参数(第一个是state为成功时调用,第二个是失败时调用),
// 这两个函数可以通过接收resolve("请求成功时的结果")或reject("请求失败时的结果")传递的结果参数,来接收请求结果
//返回值:是一个新的promise对象实例t,且promise状态时pending
// promise支持链式操作,promise里面的状态不改变(没有调用resolve或reject),则不会执行tnen里面的方法
const t = p.then((value) => {
console.dir(value)
//如何改变t的状态:使用return可以将返回的新promise实例的状态改为fulfilled,使得then继续执行
//如果在then方法的代码出错,会将新promise的状态改成rejected
//console.log(a)
return 123
}, (reason) => {
console.log(reason)
})
// promise支持链式操作
t.then(
(value) => {
console.log("成功2", value)
}, (reason) => {
console.log(reason)
})
用promise解决回调地狱
//封装函数,目的返回一个promise实例(带参数)
function getData(url, data = {}) {
return new Promise((resolve, reject) => {
$.ajax(
{
type: "get",
url: url,
data: data,
success: function (res) {
resolve(res)
},
error: function () {
reject(res)
}
}
);
})
}
// 解决回调地狱
getData("data1.json")//到这里为止产生了一个带有第一次ajax请求结果值的promise新实例,
//且这个实例的状态不是pending【p1】
.then((data) => {
const { id } = data;//对象解构赋值
return getData("data2.json", id)
})//到这里为止产生了一个带有第2次ajax请求结果值的promise新实例,
//且这个实例的状态不是pending【p2】
.then((data) => {
const { username } = data;//对象解构赋值
return getData("data3.json", username)
})//到此产生了带第3次Ajax请求结果的promises实例【p3】
.then((data) => {
console.log(data)
})
Promise.all
Promise.all(iterable)返回一个新的Promise实例,此实例在iterable参数内素有的Promise都fulfilled或者参数中不包含Promise时,
状态变成fulfilled。 如果参数中Promise有一个失败rejected ,此实例回调失败,失败原因的是第一个失败Promise的返回结果
let p = Promise.all([p1,p2,p3])
复制代码p的状态由 p1,p2,p3决定,分成以下;两种情况:
(1)只有p1、p2、p3的状态都变成 fulfilled,p的状态才会变成 fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被 rejected,p的状态就变成 rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
Promise.all 的特点
Promise.all的返回值是一个Promise实例
Promise.all = function (promise) {
return new Promise((resolve, reject) => {
let index = 0
let result = []
if (promise.length === 0) {
resolve(result)
} else {
//将请求成功的数据假如结果数组里面,并且判断成功的个数,当成功个数与发promise的请求数相同时,
//结果返回
function processValue(i, data) {
result[i] = data
if (++index === promise.length) {
resolve(result)
}
}
for (let i = 0; i < promise.length; i++) {
Promise.resolve(promise[i]).then((data) => {
processValue(i, data)
}, (err) => {//一旦有一个请求失败,立刻抛出错误,不再执行 reject(err)
return
})
}
}
})
}
Promise.race()
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,
返回的 promise就会解决或拒绝
一个有用的场景是,从多个镜像服务器下载资源,一旦有一个返回,其它的返回也就不用处理了
.Promise.prototype.finally()
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
promise
.then(result => {···})
.catch(error => {···})
.finally(()=>{···});
上面代码中,不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
下面是一个例子,服务器使用 Promise 处理请求,然后使用finally方法关掉服务器。
server.listen(port)
.then(function() {
// ...
})
.finally(server.stop);
finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。
finally本质上是then方法的特例。
什么是async/await?
async/await是写异步代码的新方式,以前的方法有回调函数和Promise。
async/await是基于Promise实现的,它不能用于普通的回调函数。
async/await与Promise一样,是非阻塞的。
async/await使得异步代码看起来像同步代码,这正是它的魔力所在。
用法
async用于申明一个function是异步的,而await可以认为是async wait的简写,等待一个异步方法执行完成。
规则:
1 async和await是配对使用的,await存在于async的内部。否则会报错
2 await表示在这里等待一个promise返回,再接下来执行
3 await后面跟着的应该是一个promise对象,(也可以不是,如果不是接下来也没什么意义了…)
promise是ES6,async/await是ES7
async/await相对于promise来讲,写法更加优雅
reject状态:
1)promise错误可以通过catch来捕捉,建议尾部捕获错误,
2)async/await既可以用.then又可以用try-catch捕捉
//发送ajax请求(封装功能函数、功能组件)
/* 1.封装功能函数
1.功能点明确
2.函数内部应保留固定代码(静态的)
3.将动态数据抽取成参数,由使用者根据自身需求传入
4.一个良好的函数应该设置形参的默认值(es6的形参默认值)
2.封装功能组件
1.功能点明确
2.组件内部保留静态代码
3.将动态数据抽取成props参数,由使用者以标签属性形式动态传入props数据
4.一个良好的组件应该设置组件的必要性及数据类型
props:{
msg:{
required:true,
type:string,
}
}
*/
//还要解决异步问题
import config from "./config"
export default (url, data = {}, method = "GET") => {
return new Promise((resolve, reject) => {
// 区分登录登录请求和其它请求,登录请求时,把cookies信息保存到本地
wx.request({
url: config.host + url,
data,
method,
//判断是否有cookies
header: {
cookie: wx.getStorageSync('cookies') ? wx.getStorageSync('cookies').filter((item) => {
return item.includes("MUSIC_U")
})[0] : ""
},
success: (res) => {
resolve(res.data)
console.log("请求成功", res)
//判断是否为的登陆请求
if (data.islogin) {
wx.setStorageSync('cookies', res.cookies);
}
},
fail: (err) => {
reject(err)
console.log("请求失败")
}
})
}
)
}
// 获取视频列表数据
async getVideoLiatData(navid) {
let videoData = await request("/video/group", {
id: navid
})
let videoId = 0;
this.setData({
videoList: videoData.datas.map((item) => {
item["id"] = videoId++;
return item
})
})