Promise

一、同步和异步

1.1 吃外卖的文学-同步和异步

采用异步方式时, 在空闲期间我们可以做其他事情。

而同步时,我们在空闲期间只能等待, 什么事都不做

1.2 同步和异步的区别

在计算机领域,

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;

异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率

1.3 js代码的执行顺序-同步和异步

js的执行顺序,先同步后异步

 如上图:任务二属于异步代码(耗时操作)

异步任务:

  • 定时器:setTimeout setInterval
  • ajax的异步请求的xhr.onreadystate = function(){}
  • es6的promise
console.log(1);
setTimeOut(function(){
   console.log(2);
},0)
console.log(3);

-------------------------------

console.log(1);
 var xhr = new XMLHttpRequest();
 console.log(2);
 xhr.open('get','checkUser.php?username='+this.value);
 console.log(3);
 xhr.send();
 console.log(4);
 xhr.onreadystatechange = function(){
   if (xhr.readyState==4&&xhr.status==200) {
  		 console.log(5);
   }
 }

 console.log(6);

 

1.4、获取取异步函数返回值

function getNum(){
  return 1;
}

function getNum(){
   setTimeOut(function(){
       return 1;
   },1000);
}
------------------------------------

解决方案:回调函数来解决

 function getNum(callback){
      setTimeout(function(){
          callback(1);
      },500)
  }


getNum(function(data){
    console.log(data);
})

1.5 多个异步任务,顺序执行 

1.5.1 回调函数嵌套

  setTimeout(function () {
        console.log(1);
        setTimeout(function () {
            console.log(2);
            setTimeout(function () {
                console.log(3);
                setTimeout(function () {
                    console.log(4);
                }, 2000)
            }, 3000)
        }, 5000)
    }, 1000)

 

问题:

  1. 代码丑,冗杂,难维护
  2. 执行效率低

1.5.2 Promise解决(下面讲解)

问题:编写的难度比传统写法高,并且阅读代码也不是一眼能够看懂。

你只会看到一堆then,必须本身在then的回调函数里面理清逻辑。

三、Promise完美解决回调地狱

3.1 Promise对象

Promise(承诺),在程序中的意思就是承诺我过一段时间(通常是一个异步操作)后会给你一个结果,是异步编程的一种解决方案

从语法上说,原生Promise 是一个对象,从它可以获取异步操作的消息

Promise 提供统一的 API,各种异步操作都可以用同步的写法进行处理。

3.2 Promise实现原理

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。

它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

promise对象的方法:

  1. then()方法就是把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数
  2. 而 Promise的优势就在于这个链式调用。
  1. 我们可以在 then 方法中继续写 Promise 对象并返回,然后继续调用 then 来进行回调操作。

 


cpnst p = new Promise(
  function (resolve, reject) {
    // 一段耗时的异步操作
    resolve('成功') // 获取成功的数据
    // reject('失败') //获取失败的结果
  }
).then(res=>{console.log(res)})


-----------------------------------------------
const p1 = new Promise(function(resolve,reject){
      resolve(1)
  })
  const p2 = new Promise(function(resolve,reject){
      resolve(2)
  })
  const p3 = new Promise(function(resolve,reject){
      resolve(3)
  })
  const p4 = new Promise(function(resolve,reject){
      resolve(4)
  })


  p1.then(data=>{console.log(data);return p2;})
    .then(data=>{console.log(data);return p3;})
    .then(data=>{console.log(data);})

3.3 Promise特点

  1. 对象的状态不受外界影响。

promise有三种状态 pending(进行中) fulfilled(已成功) rejected(已失败),只有异步操作的结果,才可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。一旦从等待状态变成为其他状态就永远不能更改状态了。

promise只有两种状态改变:

pending(进行中)–> fulfilled(已成功) ;

pending(进行中)–> rejected(已失败)。

当状态改变结束时称为resolve(已固·定),一旦状态变为 resolved 后,就不能再次改变为Fulfilled。

一旦新建Promise就会立即执行,无法中途取消

 let p = new Promise((resolve, reject) => {
        let n = Math.round(Math.random() * 10 + 10);//10-20
        if (n <= 15) {
            resolve(n)
        } else {
            reject(n);
        }
})
    console.log(p);//promise对象

 p对象:.then()拿到处理成功的结果   .catch()拿处理失败的结果的
 p.then(data=>{
   console.log(data);
  }).catch(data=>{
    console.log(data);
  })


三个状态:"pending", "fulfilled","rejected"
 2个方法:.then()  .catch()

 3.4 使用Promise封装ajax

   function $promise(options) {
        return new Promise((resolve, reject) => {
            // 1. 创建xhr对象  XMLHTTPRequset
            let xhr = new XMLHttpRequest();
            let params = formdata(options.data);
            // 2. 设置请求参数(分get和post)
            if (options.type == 'GET') {
                xhr.open('get', options.url + '?' + options.data, true);
                xhr.send();
            }
            if (options.type == 'POST') {
                xhr.open('post', options.url);
                xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                xhr.send( options.data);
            }
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status == 200) {
                        resolve(xhr.responseText)
                    } else {
                        reject('错误');
                    }
                }
            }
        })
    }
    
     $promise({
        type: "GET",
        url: 'a.php',
        asycn: true,
        data: "username=zhangsan"
    }).then(data => {
        console.log(data);
    })
    

四、async 和await(了解)

  用async/ await来发送异步请求,从服务端获取数据,代码很简洁
  
  async/await:基于prmoise,await修饰promise对象,async 修饰函数
   function getNum1(){
      return 1;
   }
   function getNum2(){
      return 2;
   }


     async function fn(){
       let res1 = await getNum1();
       let res2 = await getNum2();
       console.log(res1);
       console.log(res2);
    }

    fn();
     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值