Promise学习笔记

一、概念

Promise对象是JavaScript异步操作解决方案,为异步操作提供统一接口。Promise对象的三种状态:未完成(pending)、已完成(fulfilled)、失败(rejected)

二、对象的使用

1、封装函数创建对象

function getFoo() {
    let p=new Promise((resolve,reject)=>{
        if (/* 异步操作成功 */true) {
            resolve(value);
        }else{
            reject(error);
        }
    });
    return p;
}

2、then( )方法

指定resolve方法和reject方法的回调函数

const prom=getFoo();
prom.then(v=>{
   // success
},e=>{
  // failure
})

三、JavaScript异步

1、同步

function fun1() {
   console.log("函数1");
 }
 function fun2() {
   console.log("函数2");
 }
 fun1();
 fun2();

2、异步

a、同步回调

function fun1(fun) {
    console.log("函数1");
    fun();
}
function fun2() {
  console.log("函数2");
}
fun1(fun2);

b、异步回调

function fun1(fun) {
    setTimeout(function () {
         fun();
       }, 0);
       console.log("函数1");        
}
function fun2() {
  console.log("函数2");
}
fun1(fun2);
for (let i = 0; i <= 10000; i++) {
  console.log("i:", i);
}

在异步回调时,就算fun2()函数放在最上面,而且fun1()函数外面有一个大的for循环,打印结果:

函数1
i:0
......
i:10000
函数2

而且,setTimeout函数的延时为0;到此,我对异步的理解为,当JS文件内所有的同步事件结束后,再回过头来执行所有的异步事件,而异步事件也是按照其所在的异步事件等级(比如异步中包含异步,形成第一级异步、第二级异步…)形成同等级异步的同步事件。(后来我又看到,异步事件又分为宏队列和微队列,详见四)

c、ajax异步

AJAX中根据async的值不同分为同步(async = false)和异步(async = true)
在异步模式下:
****首先:js向服务器发出请求,在等待数据时,ajax后面的同步事件按序依次执行。这样,如果等待数据的时间过长或者等不到数据,都不影响其他事件的执行。
****其次:当数据返回成功时,ajax调用回调函数处理数据。这里有个问题,就是数据返回得很快,js也不是立即执行回调函数,由于是异步事件,需要等同步事件都执行完后再开始执行异步事件。也就是,如果js文件的同步事件执行完需要10分钟(夸张了点),而ajax数据1分钟就返回成功了,但是对不起,ajax的回调函数得10分钟后执行。

$.ajax({
  type: "get",
  url: "./data/productlist.json",
  dataType: "json",
  success: function (data) {
    console.log(data);
  },
});
function fun1(fun) {
  setTimeout(function () {
    fun();
  }, 0);
  console.log(1);
}
function fun2() {
  console.log(2);
}
fun1(fun2);
for (let i = 0; i <= 500; i++) {
  console.log("i:", i);
}
for (let i = 0; i <= 500; i++) {
  console.log("b:", i);
}

再次:在上例中,ajax异步和fun2异步两个回调函数,处于同级别异步事件中,按次序执行。这样就又回到了原问题,当ajax异步回调函数执行时间过长时,将会影响到其他异步事件的执行。有办法,让异步函数的的回调函数,也变成异步,由此,**“回调地狱”**到来了。

$.ajax({
   type: "get",
   url: "./data/productlist.json",
   dataType: "json",
   success: function (data) {
       setTimeout(function () {
           console.log(data);
       }, 0);         
   },
 });

3、ES6新的对象Promise

Promise提供了一种更合理、更强大的异步解决方案,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

const prom=getFoo();
prom.then(v=>{
   // success
},e=>{
  // failure
})

prom.then(回调函数),而且,prom.then(回调函数)也是一个Promise对象,**“回调地狱”**可以写成prom.then(回调函数1).then(回调函数2).then(回调函数3).then(回调函数4)…
网上一个同学的面试题:https://www.jianshu.com/p/c613c0198430

var promise = new Promise(function(resolve, reject) {
    console.log('Promise instance');
    resolve();
});

promise.then(function() {
   console.log('resolved result');
});
for(var i=0;i<100;i++) {
console.log(i);
}

程序的打印顺序

4、迭代器(Iterator)和生成器(Generator)

ES6新增的异步操作的方法,还没有好好学

5、async和await

在ES7中,async函数处理异步,是生成器的一种语法糖,简化了外部执行器的代码,同时利用await替代yield,async替代生成器的(*)号。
参考:https://zhuanlan.zhihu.com/p/74637286

四、回调队列和事件循环(event loop)

1、event loop

event loop它最主要是分三部分:主线程、宏队列(macrotask)、微队列(microtask)。
js的任务队列分为同步任务和异步任务,所有的同步任务都是在主线程里执行的,异步任务可能会在macrotask或者microtask里面。

2、宏队列

setTimeout、setInterval、setImmediate、I/O、UI rendering
DOM 的回调、Ajax 的回调

3、微队列

promise.then、process.nextTick
在这里插入图片描述

4、执行顺序(同步->微任务->宏任务)

• JS 引擎先去执行所有的同步代码
• 然后执行队列中的任务
• 在一个一个宏任务执行前,会先检查微任务的执行,必须等所有微任务执行完才会一个一个去执行宏任务

5、流行的面试题

async function asycn1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}

async function async2() {
  console.log('async2');
}

console.log('script start');

setTimeout(() => {
  console.log('setTimeout ');
}, 0);

asycn1();

new Promise((resolve) => {
  console.log('promise1');
  resolve();
}).then(() => {
  console.log('promise2');
});

console.log('script end');

参考:https://blog.csdn.net/weixin_41884153/article/details/90737448
https://www.cnblogs.com/BAHG/p/12921321.html
https://blog.csdn.net/weixin_44138611/article/details/112464382

五、then方法中返回return

应用场景:在页面加载时,异步函数A获得对象数组arr,再调用一个函数B对数组arr进行过滤,而这个函数B里有用另一个异步函数C的结果再进行一次过滤,过滤出来的结果返回给A继续使用处理。
一个问题:如果函数B是个普通函数,那么异步函数C里的结果resultArr我没有办法return resultArr出来,需要将函数B做成Promiss对象

// 函数A
getObjectData('objDetail').then(res => {
    payMonth(res,selectMonth.split('-')[1],selectMonth.split('-')[0]).then(res=>{
        console.log(res);
    })
})
// 函数B
// 月支出总计
export function payMonth(arr,month,year){
    let dateArr=new Promise((resolve,reject)=>{
    let monthArr=[]
    let payClassMon=''
    let payArr = arr.filter(item =>
        item.incomePay == 0 && item.date.split(' ')[0].split('-')[0] == year && item.date.split(' ')[0].split('-')[1]==month
    )
    if (payArr) {
        // 月总支出
        let pay = payArr.reduce((total, value, index, array) => {
            return total + parseFloat(value.money);
        }, 0) 
        monthArr.push({'payMonthCount':pay})
        // 类别 函数C
        getObjectData('classIncome').then(res=>{
            if (res) {
                for(let ele of res){
                    let payClassArr = payArr.filter(item =>
                        item.aclass==ele
                    )
                    if (payClassArr.length>0) {
                        payClassMon = payClassArr.reduce((total, value, index, array) => {
                            return total + parseFloat(value.money);
                        }, 0)
                        monthArr.push({'aclass':ele,'classPay':payClassMon})
                    }
                }  
            }
            resolve(monthArr);     
        })
    }
})
return dateArr;
}
微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值