JS Promise笔记

ES6–Promise对象

定义:
  • JS中进行异步编程的新的解决方案 (旧的是纯回调函数)
  • 从语法上说,: Promise 是一个构造函数
  • 从功能上说: promise对象用来封装一个异步操作并可以获得其结果
优点:
  1. 指定回调函数的方式更加灵活

    promise: 启动异步任务 => 返回Promise对象 => 给Promise对象绑定回调函数 (甚至可以在异步任务结束后再绑定)

  2. 支持链式调用, 可以解决回调地狱问题

/*
	async , await 回调地狱的终极解决方案
	同步的编码方式, 没有回调函数
*/
async function request() {
    try{
        const result = await doSomething()
        const newResult = await doSomethingElse(result)
        const finalResult = await doThirdthing(newResult)
    } catch(error) {
        failureCallback(error)
    }
}

Promise对象:代表了未来某个将要发生的操作,通常是异步操作
promise对象可以将异步操作以同步的流程表达出来,避免了层层嵌套的
回调函数(回调地域),ES6的Promise是一个构造函数,用来生成promise实例

execute 执行器函数, 同步执行

常见的API:
const p1 = new Promise((resolve, reject)=> {
    resolve('1')
}).then().catch()

const p2 = Promise.resolve('2') // 语法糖
p2.then()

const p3 = Promise.reject('3')
p3.catch()

const pAll = Promise.all([p1, p2, p3])
// pAll 也是一个Promise对象, 只有当后面所有Promise的状态为成功时, 才是成功
pAll.then(
	values => {},     // 成功得到的值是resolve()中参数的集合, 顺序一一对应
    reason => {}      // 失败得到的值是reject() 里的参数 
)

const pRace = Promise.race([p1,p2,p3])
// 哪个执行快结果就是哪个
pRace.then(
	value => {},     
    reason => {}
)
基本步骤:
  1. 创建promise对象
  2. 调用promise的then()

then() 方法返回的结果是 Promise 对象, 对象状态由回调函数的执行结果决定

如果回调函数中返回的结果是 非Promise类型的属性, 状态为成功, 返回值为对象的值

如果返回的结果是Promise类型的属性, 则 该promise内部返回的状态 就决定 then方法 promise 对象的状态

如果抛出异常,新promise 的状态变为 resolved ,reason 为抛出的异常

new Promise((resolve, reject) => {
    reject('A')
}).then(
	value => {
        console.log('onResolved 1 ' + value)
        
    },
    reason => {
         console.log('onRejected 1 ' + reason)
         return undefined
    }
).then(
	value => {
        console.log('onResolved 2 ' + value)
    },
    reason => {
         console.log('onRejected 2 ' + reason)
    }
)
//     output:   onRejected 1 A     onResolved 2 undefined
  • 链式调用 p.then(value => {} ).then( value => {} )
const p = new Promise( resolve => {
    resolve('A')
});
p.then(value => {
    return new Promise( resolve => {
        resolve(value+'B')
    })
}).then(value => {
    return new Promise(resolve => {
        resolve(value+'C')
    })
}).then(value=>{
        console.log(value) // ABC
})
  • 当一个promise指定多个成功 / 失败回调函数,时, 都会调用
  1. promise的三个状态:
  • pending:初始化,

  • fullfilled:成功,

  • rejected:失败

    // 除了 resolve() 和 reject() , 抛出异常也可以使promise 的状态 从pending 变为 rejected
    const p = new Promise((resolve, reject) => {
        throw new Error('出错误了')
        // throw 3
    })
    p.catch(reason => {
        console.log(reason)
    })
    
  1. 应用:
  • 使用promise实现超时处理,
  • 使用promise封装处理ajax请求
  • 使用promise实现封装处理ajax请求
let promise = new Promise((resolve,reject)=>{
            console.log("111");
            //执行异步操作通常是发送ajax请求,开启定时器
            setTimeout(()=>{
                console.log("333");
                //根据异步任务的返回结果来修改promise的状态
                //异步任务执行成功
                
                resolve("哈哈");//修改promise的状态为fullfilled;成功状态
                // reject();//修改为失败状态
            },2000);
            console.log("222");
        }).catch((e)=>{});
        promise.then((data)=>{//成功的回调,也可以写上参数resolve
                console.log(data,'成功了');
            },()=>{//失败的回调
                console.log('失败了');
            });

Promise例子—用ajax获取新闻内容

//promise对象案例练习
            //获取新闻内容
            function getNews(url){
                let promise = new Promise((resolve,reject)=>{
                    //状态:初始化
                    //执行异步任务
                    //创建xmlHttp实例对象
                    let xmlHttp = new XMLHttpRequest();
                    //绑定监听 readyState
                    xmlHttp.onreadystatechange = function(){
                        if(xmlHttp.readyState==4){
                            if(xmlHttp.status==200){//请求成功
                                console.log(xmlHttp.responseText);
                                resolve(xmlHttp.responseText);//修改promise的状态为成功状态
                            }
                        }else{//请求失败
                            reject("暂时没有数据");
                        }
                    };
                     xmlHttp.open('GET',url);
                     xmlHttp.send();
                });
               return promise;
            }
            getNews("address url")
            .then((data)=>{
                console.log(data);
                //发送请求获取内容
                let theCommemnt = JSON.parse(data).commemntUrl;//commentUrl是data数据里面的一个地址
                let url =  "address url"+theCommemnt;
                return getNews(url);
            },(err)=>{
                console.log(err);
            })
            .then((data)=>{
                 console.log(data);//上面的then返回的数据
            },()=>{

            });

  1. 关键问题

    1). 改变Promise 状态和指定回调函数 谁先谁后?

    • 都有可能, 正常情况下先指定回调函数再改变状态, 但也可以相反
    • 如何先改状态再指定回调?
      • 再执行器中直接调用 resolve() / reject()
      • 延迟更长时间才调用 then()
    • 什么时候才能得到数据
      • 如果先指定的回调, 那当状态发生改变时,回调函数就会调用, 得到数据
      • 如果先改变的状态,那当指定回调时,回调函数就会调用, 得到数据

    2). 异常传透

    • 使用promise 的then链式调用时,可以在最后指定失败的回调

    • 前面任何操作出了异常,都会传到最后失败的回调中处理

      new Promise((resolve, reject) => {
          reject(1)
      }).then(
      	value => { return 2 },
          reason => {  throw reason }     // 相当于抛出异常
      ).then(
      	value => { return 3 },
      ).catch(reason => {
          console.log(reason)
      })
      

    3).中断Promise链

    • 使用promise 的then链式调用时,在中间中断, 不再调用后面的回调函数

    • 办法: 在回调函数中返回一个 pending 状态的 promise

      new Promise((resolve, reject) => {
          reject(1)
      }).then(
      	value => { return 2 },
          reason => {  throw reason }     // 相当于抛出异常
      ).then(
      	value => { return 3 },
      ).catch(reason => {
          console.log(reason)
          return new Promise(() => {})  // 返回一个pending状态的promise, 中断promise链
      }).then()
      
自定义Promise

八、ES6–Symbol属性

Symbol:ES6中添加了一种原始数据类型symbol(已有的原始数据类型:
String,Number,Boolean,undefined,null,对象)
Symbol属性对应的值是唯一的,解决命名冲突问题,Symbol值不能与其他
数据进行计算,包括同字符串拼串,for in,for of遍历时不会遍历Symbol属性
使用:调用Symbol函数得到symbol值
let symbol = Symbol();
let obj={};
obj[symbol] = “hello”;
2.传参标识
let symbol = Symbol(“one”);
let symbol2 = Symbol(“two”);
console.log(symbol,symbol2);
3.内置Symbol值
除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向
语言内部的使用的方法。
Symbol.iterator:指向该对象默认的遍历方法

 let symbol = Symbol("hello");
    // alert(typeof symbol);
    console.log(symbol);
    // console.log(symbol.toString());
    let obj = {username:'xiaozhan',age:29};
    obj[symbol] = "hello";
    console.log(obj);
    //for in ,for of 不能遍历Symbol属性
    for(let i in obj){
        console.log(i);
    }
    let symbol1 = Symbol('one');
    let symbol2 = Symbol('two');
     console.log(symbol1==symbol2);//false
    //可以用来定义常量
    const The_Key = Symbol('the_key');
    console.log(The_Key);

2.遍历Set
3.遍历Map
4.遍历字符串
5.遍历伪数组

//数组去重方法
 let arr = [1,2,3,4,5,5,6,2];
                    let arr1 = arr;
                    arr = [];
                    let set=new Set(arr1);
                    for(let i of set){
                        arr.push(i);
                    }
                    console.log(...arr);
                    
                    let arr3 = [1,2,3,4,5,5,6,2];
                    let set2 = new Set(arr3);
                    console.log(...set2);

                    let btns = document.getElementsByTagName("button");
                    for(let j of btns){
                        console.log(j);
                    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值