🍉ES6 promise对象

88 阅读2分钟

官方文档:ES6 Promise对象 - ES6文档 (caibaojian.com)

接口调用方式

  • 原生ajax
  • 基于jQuery的ajax
  • fetch
  • axios

异步

  • JavaScript的执行环境是「单线程」

  • 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程

  • 异步模式可以一起执行多个任务

  • JS中常见的异步调用

    • 定时任务
    • ajax
    • 事件函数

promise

  • 主要解决异步深层嵌套的问题
  • promise 提供了简洁的API 使得异步操作更加容易

1.Promise基本使用

  • 使用new来构建一个Promise , Promise的构造函数接收一个参数,是函数,并且传入两个参数: resolvereject, 分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数

  • Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
 <script>
    //1.Promise基本使用
    const p=new Promise(function (reslove,reject){
        //let data='成功';
        //reslove(data);
       let err='失败';
       reject(err);
    })
    p.then(function (value){
        console.log(value);
    },function(reason){
        console.log(reason);
    });
</script>  
</body>
</html>

2.Promise封装

//引入fs模块!!!
const fs=require('fs');
const p=new Promise(function (reslove,reject){
    fs.readFile('./lianx/s.txt',(err,data)=>{
    if(err) reject(err);
    reslove(data)
 });
});
p.then(function (value){
    console.log(value.toString());
},function(reason){
    console.log(reason);//读取失败
})

3.Promise封装Ajax请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
<script>
//Promise封装Ajax请求
const p=new Promise( (reslove,reject)=>{
//1.创建对象
const xhr=new XMLHttpRequest();
//2.初始化
xhr.open('GET',"https://api.apiopen.top/getJoke");
//3.发送
xhr.send();
//4.绑定时间
xhr.onreadystatechange=function(){
    if(xhr.status>=200 && xhr.status<=299){
       reslove(xhr.response);
    }else{
        reject(xhr.status);
    }
}
});
//指定回调
p.then(function (value){
    console.log(value)
},function(reason){
    console.error(reason);
})
</script>
</body>
</html>

4.使用Promise读取多个文件

//使用Promise解决回调地狱,读取多个文件
const fs=require("fs");
const p=new Promise((resolve,reject)=>{
  fs.readFile('./lianx/s.txt',(err,data)=>{
    resolve(data);
  });
});

p.then(value=>{//value是第一个文件内容
    return new Promise( (resolve,reject)=>{
     fs.readFile('./lianx/h.txt',(err,data)=>{
      resolve([value,data]);
     });
    })
}).then(value =>{
    return new Promise( (resolve,reject)=>{
        fs.readFile('./lianx/y.txt',(err,data)=>{
         resolve([...value,data]);
        });
}).then(value=>{
    console.log(value.join('\r\n'));
})
})

image.png Promise的then方法

  • then中参数: then方法指定resolved状态和reject状态的回调函数

  • then返回值: 可以返回一个非promise对象与一个promise对象

1、如果回调函数中返回的结果是 非promise 类型的数据,状态为成功,返回值为对象的成功值resolved

2、如果...是promise类型的数据 此Promise对象的状态决定上面Promise对象p的状态

5.Promise 基本API

实例方法

.then()
得到异步任务正确的结果

.catch()
获取异常信息

.finally()
成功与否都会执行(不是正式标准)

  <script type="text/javascript">
    /*
      Promise常用API-实例方法
    */
    // console.dir(Promise);
    function foo() {
      return new Promise(function(resolve, reject){
        setTimeout(function(){
          // resolve(123);
          reject('error');
        }, 100);
      })
    }
    // foo()
    //   .then(function(data){
    //     console.log(data)
    //   })
    //   .catch(function(data){
    //     console.log(data)
    //   })
    //   .finally(function(){
    //     console.log('finished')
    //   });
​
    // --------------------------
    // 两种写法是等效的
    foo()
      .then(function(data){
        # 得到异步任务正确的结果
        console.log(data)
      },function(data){
        # 获取异常信息
        console.log(data)
      })
      # 成功与否都会执行(不是正式标准) 
      .finally(function(){
        console.log('finished')
      });
  </script>
静态方法
.all()
  • Promise.all方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定
.race()
  • Promise.race方法同样接受一个数组作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilledrejected),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数
  <script type="text/javascript">
    /*
      Promise常用API-对象方法
    */
    // console.dir(Promise)
    function queryData(url) {
      return new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
          if(xhr.readyState != 4) return;
          if(xhr.readyState == 4 && xhr.status == 200) {
            // 处理正常的情况
            resolve(xhr.responseText);
          }else{
            // 处理异常情况
            reject('服务器错误');
          }
        };
        xhr.open('get', url);
        xhr.send(null);
      });
    }
​
    var p1 = queryData('http://localhost:3000/a1');
    var p2 = queryData('http://localhost:3000/a2');
    var p3 = queryData('http://localhost:3000/a3');
     Promise.all([p1,p2,p3]).then(function(result){
       //   all 中的参数  [p1,p2,p3]   和 返回的结果一 一对应["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
       console.log(result) //["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
     })
    Promise.race([p1,p2,p3]).then(function(result){
      // 由于p1执行较快,Promise的then()将获得结果'P1'。p2,p3仍在继续执行,但执行结果将被丢弃。
      console.log(result) // "HELLO TOM"
    })
  </script>