实例对象:new函数产生的对象,称为实例对象,简称对象
函数对象:将函数作为对象,称为函数对象
function Fn() { } // Fn称为函数
const fn = new Fn() //Fn()只有new过才能称为构造函数
// fn称为实例对象,简称对象
console.log(Fn.prototype); //只有函数作为对象使用才能称为函数对象
什么是promise
抽象表达:
Promise 是js中进行异步编程的新的解决方案(promise也支持回调)旧的方案是通过纯回调的方式。
具体表达:
①从语法上看:Promise是一个构造函数 (自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法)
②从功能上看:promise对象用来封装一个异步操作并可以获取其成功/失败的结果值
promise 对象状态改变
初始时是pending,表示未确定的状态,接下来可能有两种情况
pending:resloved
pending:rejected
说明:只有两种情况,并且一个promise对象只能修改改变一次
无论变为成功还是失败,都会有一个结果
成功的结果数据一般是value,失败的结构一般是reason
promise流程
promise的基本流程
//创建一个promise对象
const promise=new Promise(function(resolve,reject){
// Peomise 构造函数接受一个函数(执行器)作为参数,该函数的两个参数是(resolve,reject)
})
promise.then(function (value) {
// 第一个回调函数onResolved()
}, function (reson) {
// 第二个回调函数onRejected()
})
例子
// 创建一个新的p实列对象的promise
const p = new Promise((resolve, reject) => { //执行器函数
console.log('第一步');
// 执行异步操作
setTimeout(() => {
console.log('第三步');
const time = Date.now()//获取当前时间戳
// 如果当前时间为偶数
if (time % 2 == 0) {
resolve('成功的数据,time=' + time)
} else {
reject('失败的数据,time=' + time)
}
}, 1000)
})
console.log('第二步', p);
p.then(
value => { //接受到成功的value onresolved
console.log('成功数据', value); //成功的回调 成功的数据
}, reason => { // 接收得到失败的reason数据 onRejected
console.log('失败数据', reason); //失败的回调 失败的数据
}
)
// .then() 和执行器(executor)同步执行,.then() 中的回调函数异步执行
promise作用
promise指定的回调函数的方式更加灵活
纯回调方式
//一个名为 createAudioFileAsync() 的函数,它接收一些配置和两个回调函数,然后异步地生成音频文件。
// 一个回调函数在文件成功创建时被调用,另一个则在出现异常时被调用
// 成功的回调函数、
function successCallback(result) {
console.log('声音文件创建成功:' + result);
}
// 失败的回调
function failureCallback(error) {
console.log('声音文件创建失败:' + error);
}
// 必须指定回调函数。在执行异步任务
createAudioFileAsync(audioSettings, successCallback, failureCallback)
promise调用
// 2. 使用Promise
const promise = createAudioFileAsync(audioSettings); // 执行2秒
setTimeout(() => {
promise.then(successCallback, failureCallback) // 也可以获取
}, 3000);
// // 简写:
// createAudioFileAsync(audioSettings).then(successCallback, failureCallback)
promise解决回调地狱问题
纯回调函数可能出现回调函数
setTimeout(function () { //第一层
console.log('aaaa');
setTimeout(function () { //第二程
console.log('bbbb');
setTimeout(function () { //第三层
console.log('ccccc');
}, 1000)
}, 2000)
}, 3000)
promise链式
function fn(str) {
var p = new Promise((reslove, reject) => {
// 处理异步数据
var flag = true
setTimeout(() => {
if (flag) {
reslove(str)
}
else {
reject(error)
}
})
})
return p
}
fn(aaa)
.then(value => {
console.log('第一步',value); //aaa
return fn(bbb)
})
.then(value => {
console.log('第二步',value);//bbb
return fn(ccc)
})
.then(value => {
console.log('第三步',value);//ccc
})
.catch(error => {
console.log(error);
})
fn(aaa),fn(bbb),fn(ccc)得到的都是promise对象代码整体是纵向,可阅读性好。所有的then()只写了成功的回调,任何的失败回调会通过异常传透到最下面的catch被捕获。
使用async/await
首先我们看见async关键字,他作为一个关键字放在声明对象的前面,表示函数是一个异步函数,不会阻塞函数的执行,async函数赶回数据时自动封装为一个promise对象
async function fn() {
var flag = true
if (flag) {
return '第二步'
}
else {
throw '处理失败'
}
}
fn()
.then(value => {
console.log(value);
})
.catch(reson => {
console.log(reson);
})
console.log('第一步');
await关键字
1.await关键字只能在使用async定义函数中使用
2.await后面可以直接跟一个promise实例对象(可以是任意表达式,更多的是跟一个返回promise对象的表达式)
3.await不能单独使用
4.await可以直接拿到promise中resolve的数据
封装成一个可以返回promise的异步任务
async function fn() {
var flag = true
if (flag) {
return '第二步'
}
else {
throw '处理失败'
}
}
fn()
.then(value => {
console.log(value);
})
.catch(reson => {
console.log(reson);
})
console.log('第一步');
async/await
// 封装一个可以返回promise的异步任务
function fn(str) {
var p = new Promise((resolve, reject) => {
var flag = false
if (flag) {
resolve(str)
} else {
reject('处理失败了呀')
}
})
return p
}
// 封装一个可以执行上述异步任务的async函数
async function test() {
try {
const res1 = await fn('你好呀1');
const res2 = await fn('你好呀2');
const res3 = await fn('你好呀3');
console.log(res1, res2, res3);
}
catch (error) {
console.log(error);
}
}
test()
总结:为什么叫await等待呢,因为当代码执行到async函数中的await时,代码就在此处等待,不在往下继续执行
,知道await拿到promise对象中resolve的数据,才继续执行,这样保持了代码执行顺序
而且使异步代码看起来更像同步代码