promise基础

promise

promise的三种状态
1.pending 等待
2.fulfilled 完成
3.rejected 拒绝
1.promise的原型方法
1) then()
2) catch()
3) finally()
then()里面有两个参数为回调函数,第一个参数取resolve的值,第二个参数取reject的值
//方式一:
var p = new Promise(function (resolve, reject) { 
            resolve('ok');
            //reject('no');

            //resolve和reject只能二选一
        });

        //then(),取得resolve或者reject的结果
        p.then(function (res) {
            console.log('resolve:' + res);//第一个函数取resolve的值
        }, function (res) {
            console.log('reject:' + res);//第二个函数取reject的值
        });

//方式二:
var p = new Promise(function (resolve, reject) {
            //resolve('ok');
   			reject('no');
        })
        p.then(function (res) {
            console.log(res);
        }).catch(function (res) {
            console.log(res);//异常捕获,当reject时执行
        }).finally(function () {
            console.log(res);//始终执行,不管是resolve还是reject
        });
then执行成功的回调
var promise = new Promise((resolve, reject) => {
	resolve('成功') // 成功的函数调用,在调用的时候可以传递对应的参数
})

promise.then((res) => {//接收resolve传递的参数
	console.log('第1次then', res);
	return 'hi~'
})
.then((res) => {//接收resolve传递的参数
	console.log('第2次then', res);
	return 'world'
})
.then() //会发生值穿透
.then((res) => {//接收resolve传递的参数
	console.log('第3次then', res);
})

catch执行失败
var promise = new Promise((resolve, reject) => {
	reject('失败')
})
// catch默认只执行第一个  如果需要往下走,需要手动报错
promise.catch((error) => {//接收reject传递的参数
	console.log('第1次catch', error);
	throw new Error('失败了') //手动抛出异常
})
.catch((error) => {//接收reject传递的参数
	console.log('第2次catch', error);
	throw new Error('失败了')
})
.catch() //会发生值穿透
.catch((error) => {//接收reject传递的参数
	console.log('第n次catch', error);
})
2.promise的静态方法
1.all
2.race
3.reject
4.resolve
5.allSettled
//静态方法 all
function getDataA(){
            return new Promise((resolve,reject)=>{
                setTimeout(function(){
                    resolve('getDataA');
                },1000)
            })
        }

        function getDataB(){
            return new Promise((resolve,reject)=>{
                setTimeout(function(){
                    resolve('getDataB');
                },3000)
            })
        }

 // 方式一:
 var arr=[];
 getDataA().then(function(res){
    arr.push(res);
 });
 getDataB().then(function(res){
    arr.push(res);;
    console.log(arr);
 })

// 方式二: 利用promise的静态方法 all
Promise.all([getDataA(),getDataB()]).then(function(res){
    console.log(res);
})
//静态方法 race
Promise.race([getDataA(),getDataB()]).then(function(res){
     console.log(res); //getDataA
});
// 静态方法 Promise.方法名
// 返回成功状态的promis
var promise1 = Promise.resolve('hello')
console.log(promise1); //fulfilled
// 返回失败状态的promise
var promise2 = Promise.reject('错误')
console.log(promise2); //rejected

// all
// 传入一个promise数组 并且执行promise数组里面的promise(如果有一个reject 就为reject)
var promise3 = Promise.reject('错误')
var promise4 = Promise.resolve('hello')
var promise5 = Promise.resolve('1')
var promise6 = Promise.resolve('你好')
var promise7 = Promise.all([promise3, promise4, promise5, promise6])
console.log(promise7);
//传入一个promise数组 不会相互影响 返回所有结果(状态全部为成功)
var promise8 = Promise.allSettled([promise3, promise4, promise5, promise6])
console.log(promise8);
// 返回最快执行完的promise
var promise9 = Promise.race([promise3, promise4, promise5, promise6])
console.log(promise9);
promise的三种状态图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yhpKwMuk-1666795960808)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221026161135145.png)]

trycatch
try{}catch(error){} //用于捕获异常,网络连接
回调地狱
概述:回调函数的无限嵌套(不会报错),失去了维护价值和代码的可读性
示例
//传入一个函数作为回调函数 在对应代码执行完成调用
function fn1(fn) {
    setTimeout(function () {
        console.log('10');
        //走完了以后回调函数执行
        fn()
    }, 1000)
}
fn1(() => {
    console.log(1);
})
//多个回调函数嵌套 回调地狱 (回调函数的无限嵌套 代码的可读性 可维护性 已经失去了)
fn(() => {
    console.log(1);
    fn(() => {
        console.log(2);
        fn(() => {
            console.log(3);
            fn(() => {
                console.log(4);
                fn(() => {
                    console.log(5);
                    fn(() => {
                        console.log(6);
                        ....
                    })
                })
            })
        })
    })
})
promise来解决回调地狱(链式调用)

在.then里面返回一个新的promise对象,在对应的异步代码执行完后调用resolve

// promise解决回调地狱
new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log(1);
        resolve()
    }, 3000)
}).then(() => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(2);
            resolve()
        }, 2000)
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(3);
            resolve()
        })
    })
}).then(() => {
    console.log(4);
})
async和await
概述:async和await是对应的两个连用的关键字,async是修饰函数的,await 是修饰promise的。await只能在async内使用。async修饰的函数返回一个promise对象,await修饰的promise对象会占用当前的线程,直到对应的promise执行完成才会释放。
async function fn() {
    await new Promise((resolve, reject) => {
        // 如果没有放行,后面的代码不会执行
        setTimeout(() => {
            console.log('hello');
            resolve()
        })
    })
    console.log('world');
}
// async修饰函数执行会返回一个promise对象
console.log(fn());
// async修饰的函数返回的promise对象 
// 里面的报错 会使当前的promise对象的状态为rejected 
// 如果里面return内容 会传递给对应的then

async function fn1() {
    // throw new Error('错误')
    return '我是美女子'
}
fn1().then(res => {
    console.log(res);
}, (error) => {
    console.log(error);
})
// await会使用当前的函数的线程占用 直到对应的修饰的promise执行完成
// await Promise.reject() 报错
利用async和await来解决回调地狱
function fn(v, delay) {
    return new Promise((resolve, reject) => {
        // 如果没有放行,后面的代码不会执行
        setTimeout(() => {
            console.log(v);
            resolve()
        }, delay)
    })
}
async function fn1() {
    await fn(1, 1000)
    await fn(2, 3000)
    await fn(3, 100)
    await fn(4, 0)
    console.log(5);
}
fn1() // 1 2 3 4 5
总结
  • async修饰函数的
  • await修饰promise对象
  • async里面使用await 那么如果这个await修饰的promise没有执行完,那么对应的async修饰的函数返回promise状态时为pending。
  • 如果async修饰的函数内什么都没有那么对应返回的promise状态是成功(默认函数返回undefined)
  • async修饰的函数 返回值就是成功 返回的值传递给then方法
  • async修饰的函数如果里面报错 那么返回的是失败 传递的值为报的错
  • await只能在async里面使用 await会使当前的函数陷入等待
3、同步、异步
//promise是构造函数,需要new,它本身是同步的,then和catch还有finally是异步的
//promise微任务

 console.log(111);
 var p = new Promise(function (resolve, reject) {
     resolve('ok');
     console.log(222);
 });
 console.log(333);
 p.then(function (res) {
     console.log(res);
     console.log(444);
 }).finally(function () {
     console.log(555);
 });
 console.log(666);
//执行结果为: 111,222,333,666,444,555
宏任务: settimeout,setinterval,script标签,事件(onclick,readystatechange...)
微任务: promise.then,promise.catch,nextTick
执行顺序: 先同步,再异步==>异步(宏任务..微任务..微任务,下一个宏任务..微任务..微任务..)
promise解决异步的两种方式:
 function getData1(url){
            return new Promise(function(resolve,reject){
                setTimeout(function(){
                    var data={code:1,msg:'ok',data:[11,22,33]};
                    resolve(data);
                })
            })
        }

 //方式一: promise + then()
 getData1('xxxx').then(function(res){
     console.log(res);
     return getData1('xxxx');
 }).then(function(res){
     console.log(res);
     return getData1('xxxx');
 }).then(function(res){
     console.log(res);
 });
 
 //方式二: promise + async + await
 async function getters(){
     const res1 =await getData1('xxxx');
     console.log(res1);
     const res2 =await getData1('xxxx');
     console.log(res2);
     const res3 =await getData1('xxxx');
     console.log(res3);
 };
 getters();
防抖(在规定时间内只执行一次 执行最后一次)
//第一个参数是做的操作 第二个参数是等待时间
function debounce(fn,delay){
    var timer = null
    return function(){
        clearTimeout(timer);//清除上一次的等待
        //开始新的等待
        timer = setTimeout(fn,delay)
    }
}
// 调用
btns[0].onclick =  debounce(() => {
    console.log('防抖');
},1000)
节流 (在规定时间内执行第一次 减少执行次数)
//操作  执行一次的时长
function throttle(fn,delay){
    var timer = null
    return function(){
        // 判断上一次是否已经走完,如果没走完就不执行下面的代码
        if(timer){
            return
        }
        // 上一次走完了就开始下一次
        timer = setTimeout(()=>{
            fn()
            timer = null; //走完了要将节流阀设置为false
        },delay)
    }
}
// 调用
btns[1].onclick = throttle(() => {
    console.log('节流');
}, 1000)
防抖和节流的区别
  • 防抖执行最后一次 节流执行第一次
  • 防抖在规定时间内只会执行一次,节流是在规定时间内减少对应的执行次数
  • 防抖开始下一次需要先清除上一次,节流开始下一次要先判断上一次是否执行完毕
函数的柯里化(将多个参数的函数拆分为多个单参数的函数 可以自由组合)
示例
function sum(a,b){
    return a + b
}
sum(1,2) //3
简单的函数柯里化
function sum(a){
    return function(b){
        return function(c){
            return a + b + c
        }
    }
}
console.log(`sum(1)(2)(3)`, sum(1)(2)(3));//6
console.log(`sum(1)(2)`, sum(1)(2));//fn
柯里化核心:参数没够返回对应的函数,参数够了返回对应的结果
//传递一个函数 (参数没到返回函数 参数到了返回结果)
function currying(fn) {
    //获取currying传递的参数
    let args = Array.prototype.slice.call(arguments,1)
    return function () {
        //将对应的函数的参数和curry传递参数做连接
        let arg = Array.from(arguments).concat(args)
        //判断参数个数是否一样
        if(arg.length < fn.length){
            //参数没到返回函数
            return currying.call(this,fn,...arg)
        }else{
            //参数到了 调用方法返回结果
            return fn.apply(this,arg)
        }
    }
}

调用

function sum(a,b,c){
    return a+b+c
}
console.log(`sum(1,2,3)`, sum(1,2,3));
let fn = currying(sum)
console.log(`fn(2)`, fn(2));//函数
console.log(`fn(2)(3)`, fn(2)(3));//函数
console.log(`fn(2)(3)(1)`, fn(2)(3)(1));//6
console.log(` fn()()()(2)()()(3)()()()(1)`, fn()()()(2)()()(3)()()()(10));//15
  //参数没到返回函数
        return currying.call(this,fn,...arg)
    }else{
        //参数到了 调用方法返回结果
        return fn.apply(this,arg)
    }
}

}


调用

```js
function sum(a,b,c){
    return a+b+c
}
console.log(`sum(1,2,3)`, sum(1,2,3));
let fn = currying(sum)
console.log(`fn(2)`, fn(2));//函数
console.log(`fn(2)(3)`, fn(2)(3));//函数
console.log(`fn(2)(3)(1)`, fn(2)(3)(1));//6
console.log(` fn()()()(2)()()(3)()()()(1)`, fn()()()(2)()()(3)()()()(10));//15
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值