当前位置: 首页 > news >正文

Promise的使用及简单实现

一. promise是什么

简单来说是一种异步流程的控制手段

  • 所谓Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise 对象的状态不受外界影响

  • 在JavaScript的世界中,所有代码都是单线程执行的。 由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。

    异步执行容易造成回调地狱

    例如:

    $.ajax(
        success(){
            $.ajax(
                success(){
                    
                }
            )
        }
    )
    复制代码

    使用promise的链式调用就可以很好的解决这个问题

    例如:vue-resource

    this.$http.post(url,parms).then(res => {
        console.log(res)
    },err => {
        
    }).then(res=>{
        
    },err=>{
        
    })
    复制代码

二.promise的使用及方法

ES6规定,Promise对象是一个构造函数,用来生成Promise实例。Promise本身有all、race、reject、resolve这几个方法

  • Promise只有一个参数 叫excutor执行器,默认new时就会调用
    let p = new Promise((resolve,reject)=>{ 
      // 默认promise中的executor是同步执行的
       resolve('买');
    });
    // then方法是异步调用的,事件环
    p.then((value)=>{ // value成功的原因
      console.log(value);//买
    },(err)=>{ // err失败的原因
    });
    复制代码

注意:then方法是Promise实例上的方法

  • Promise的reject、resolve方法

    promise有三种状态:resolve 成功 reject 失败 pending 等待态。 如果一旦promise成功了就不能失败,相反也是一样的,只有状态是等待的状态时才可以转化状态。pending->reject(resolve)

    1.Promise.resolve() 返回一个成功的promise

    2.Promise.reject() 返回一个失败的promise

    例:

    
    let fs = require('fs'); // fileSystem
    function read(url) {
      return new Promise((resolve, reject) => {
        fs.readFile(url, 'utf8', function (err, data) {
          if (err) reject(err);//成功返回
          resolve(data);//失败返回
        })
      })
    }
    
    复制代码
  • Promise的all、race方法

    promise可以支持多个并发的请求,获取并发请求中的数据

    1.Promise.all

    这可能是个很有用的方法,它可以统一处理多个Promise。Promise.all能将多个Promise实例包装成一个Promse实例

        let Promise1 = new Promise(function(resolve, reject){})
        let Promise2 = new Promise(function(resolve, reject){})
        let Promise3 = new Promise(function(resolve, reject){})
        
        let p = Promise.all([Promise1, Promise2, Promise3])
        
        p.then(funciton(){
          // 三个都成功则成功  
        }, function(){
          // 只要有失败,则失败 
        })
    
    复制代码

    2.Promise.race()

    与all方法类似,也可以将多个Promise实例包装成一个新的Promise实例 不同的是,all时大Promise的状态由多个小Promise共同决定,而race时由第一个转变状态的小Promise的状态决定,第一个是成功态,则转成功态,第一个失败态,则转失败态。

    ** 简单来说就是赛跑,处理多请求只取最快的 **

    let fs = require('fs'); // fileSystem
    function read(url) {
      return new Promise((resolve, reject) => {
        fs.readFile(url, 'utf8', function (err, data) {
          if (err) reject(err);//成功返回
          resolve(data);//失败返回
        })
      })
    }
    Promise.race([read('1.txt'),read('2.txt')]).then((data)=>{
      console.log(data);//最快读取完成功则成功
    },err=>{
      console.log(err);//最快读取完失败则失败
    });
    
    复制代码

三. promise的简单实现

通过上文我们已经知道Promise是一个构造函数,我们可以使用ES6的class类来创建一个Promise

下面我们创建一个class类来完成promise的then、reject、resolve方法

class Promise {
   constructor(executor) {
     // 默认状态是等待态
     this.status = 'pending';
     this.value = undefined;
     this.reason = undefined;
     // 存放成功的回调
     this.onResolvedCallbacks = [];
     // 存放失败的回调
     this.onRejectedCallbacks = [];
     let resolve = (data) => {
       if (this.status === 'pending') {
         this.value = data;
         this.status = 'resolved';
         this.onResolvedCallbacks.forEach(fn => fn());
       }
     }
     let reject = (reason) => {
       if (this.status === 'pending') {
         this.reason = reason;
         this.status = 'rejected';
         this.onRejectedCallbacks.forEach(fn => fn());
       }
     }
     try { // 执行时可能会发生异常
       executor(resolve, reject);
     } catch (e) {
       reject(e); // promise失败了
     }
   }
   then(onFulFilled, onRejected) {
     if (this.status === 'resolved') {
       onFulFilled(this.value);
     }
     if (this.status === 'rejected') {
       onRejected(this.reason);
     }
     // 当前既没有完成 也没有失败
     if (this.status === 'pending') {
       // 存放成功的回调
       this.onResolvedCallbacks.push(() => {
         onFulFilled(this.value);
       });
       // 存放失败的回调
       this.onRejectedCallbacks.push(() => {
         onRejected(this.reason);
       });
     }
   }
 }
 module.exports = Promise;
 
复制代码

完成了基本的功能,我们可以使用自己写的promise来测试一下


 let Promise = require('./promise');//引入
 let p = new Promise((resolve,reject)=>{
   resolve(123);
   reject(123);
 });
 p.then((data)=>{
   console.log('s',data);//s,123
 },(err)=>{
   console.log('e',err);//e,123
 });
 
复制代码

总结:

  • Promise是一种异步流程的控制手段

  • 每一个promise的实例上都有一个then方法,then方法中有两个参数,一个参数叫成功的函数 ,一个是失败的函数

  • Promise可以链式调用,并且可以支持多个并发的请求,获取并发请求中的数据

  • 如果一旦promise成功了就不能失败,相反也是一样的。只有状态是等待的状态时 才可以转化状态

  • Promise可以解决异步的问题,但不能说promise本身是异步的

相关文章:

  • Redis详解篇
  • 求int最大值以及int二进制
  • idea+tomcat 解决 debug超级慢 问题
  • ubuntu 安装时分辨率太小 导致无法继续安装
  • EntityFramework Core笔记:查询数据(3)
  • Entity Framework In Action--5 Domain model mapping(2)
  • 在IDEA中编译Maven项目
  • Python绘制数码管显示当前时间
  • ECSHOP 购物车数量更新时自动更新价格 不要重新点击更新数量按钮
  • 关于ansible远程执行的环境变量问题(login shell nonlogin shelll)
  • Effective C++ 学习笔记[1]
  • Spring Boot 2.0 with Spring 5 Kotlin support and Spring WebFlux functional
  • mysql表分区案例
  • C# :WinForm TextBox猜想输入和历史记录输入
  • 并发服务器:Redis案例研究分析
  • 深入了解以太坊
  • canvas 绘制双线技巧
  • echarts花样作死的坑
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • JavaScript设计模式之工厂模式
  • SAP云平台里Global Account和Sub Account的关系
  • 笨办法学C 练习34:动态数组
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 官方解决所有 npm 全局安装权限问题
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 区块链将重新定义世界
  • 小程序button引导用户授权
  • 用element的upload组件实现多图片上传和压缩
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • raise 与 raise ... from 的区别
  • 阿里云ACE认证学习知识点梳理
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • # 数据结构
  • $(selector).each()和$.each()的区别
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (003)SlickEdit Unity的补全
  • (k8s中)docker netty OOM问题记录
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (黑马C++)L06 重载与继承
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (转)Scala的“=”符号简介
  • (转载)Linux 多线程条件变量同步
  • **PHP二维数组遍历时同时赋值
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • ./configure、make、make install 命令
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .net 流——流的类型体系简单介绍
  • .NET 药厂业务系统 CPU爆高分析
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • ??eclipse的安装配置问题!??
  • @angular/cli项目构建--Dynamic.Form