• 对Promise的一些深入了解


    1.介绍promise和模仿Promise.all和Promise.race

    promise的设计主要是解决回调地狱(接收结果用回调函数来处理,但必须传入回调函数)的问题,由一层层嵌套回调函数改为由then来执行。
    例如:

     
     // callback用于接收返回结果, 异步方式
     fs.readFile("filePath", callback); 
     // 还有一种方式
     cosnt { promises: fs } = require("fs"); // 用promise包装fs模块,已经实现
     fs.readFile("filePath").then(callback);
     
    // 由上可看出,promise只是解决了回调函数的调用方式,没有彻底改变回调函数继续存在的问题。
     
    

    promise有三个状态,分别是pending, resolve,reject。只有resolve或者reject被调用,才会结束。
    promise对象可以通过new创建, 结果返回后then和catch方法会调用,resolve和reject会走then方法,catch是捕捉未处理异常的方法(比如:500,404之类)。

    值得注意的是,then方法的返回值为promise类型,如果在then中继续执行异步操作,则可以在then后面再次写一个then操作。叫做链式调用,例如:

      
      Promise.resolve("success")
      .then((res) => "异步操作")
      .then((resSecond) => console.log(resSecond)); // resSecond为“异步操作” 
      
    

    另外可直接调用resolve状态或者reject状态,例如Promise.resolve(),或者Promise.reject()方法。这两个方法直接返回结果,也可以传入一个Promise对象或者工厂函数。这两个函数本质都是内部创建了一个Promise对象,调用resolve或者reject。

    现如今很多的异步请求,异步执行方式,都在向promise靠拢。提供了很多的便利性。比如:axios,上面提到的fs模块,等等。我用过angular的subscribe,也是对异步的一种处理方式。但有点不伦不类。

    1.1 模拟异步操作,用于测试

      
      // 模拟异步请求
      const suc = function (time: number) {
        return new Promise(resolve => {
          setTimeout(() => {
            // time秒钟之后返回结果
            resolve("success"); 
          }, time);
        })
      }
    
      const rej = function (time: number) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            // time秒之后拒绝
            reject("fail"); 
          }, time);
        })
      }
      // 以上代码也可合并为一个函数,请读者自行考虑。
      
    

    1.2 Promise的all,race方法模拟

    PromiseAll方法内内只接受两个异步Promise,算是简化版了(官网api代码简介),能力有限。PromiseRace基本和官网上的差不多。

    PromiseRace: 竞争性关系,获取第一个结果(无论结果resolve或者reject),立即返回。

    PromiseAll_2:感觉使用状态控制这种不是太好啊

      
          // 准确来说,这个方法有缺陷,只要第一个返回,不管对与不对都返回,应该是所有结果都被reject掉才会返回reject,只有一个正确都要返回正确结果。可结合PromiseAll_2看
          function PromiseRace(arrs: Array): Promise<{}> {
            if (arrs.length === 0) return Promise.resolve([]);
        
            return new Promise((resolve, reject)=> {
              arrs.forEach((pro) => {
                Promise.resolve(pro).then(resolve, reject);
              });
            });
          }
      
        // 当所有结果为ture,才会返回ture
        function isAllFulfilled(states: Array): boolean {
          let res: boolean = true;
          states.forEach(state => res = res && state)
          return res;
        }
        
        // 用一种循环的方式迭代每个异步方法,如果不是函数或对象就直接作为结果返回
        function PromiseAll_2(arrs: Array): Promise<{}> {
          if (arrs.length === 0) return Promise.resolve([]);
          const states: Array = Array.from({length: arrs.length}, (item) => item = false);
          
          return new Promise((resolve, reject)=> {
            const result = [];
            arrs.forEach((pro, index) => {
              // 对输入做一个封装,如果是常数或者不是promise的这样就直接返回
              Promise.resolve(pro).then(res => {
                states[index] = true;
                result[index] = res;
                if (isAllFulfilled(states)) resolve(result);
              }, err => reject(err));
            });
          });
        }
    
        function PromiseAll(one: Promise, two: Promise): Promise<{}> {
            return new Promise((resolve, reject) => {
              let twoRes = null;
              let oneRes = null;
              // 基于两个异步互相检测,官网那个有点看不大明白。各位有什么好的代码建议不妨评论说一下
              one.then((res) => {
                oneRes = res;
                if (twoRes) resolve([oneRes, twoRes]);
              }, (err) => reject(err));
        
              two.then((res) => {
                twoRes = res;
                if (oneRes) resolve([oneRes, twoRes]);
              }, (err) => reject(err));
            });
       }
        
      PromiseAll(suc(1000), rej(2000)).then((res) => {
        console.log(res);
      }).catch((err) => console.log(err));
      
    

    1.3 小工具。

    1. 使用promisify对settimeout做个封装,单纯只是延迟执行
      
          const util  = require("util");
          // 封装settimeout延迟执行
          const delay = util.promisify(setTimeout); // 用作延迟执行,一般在await的时候用
    
         用例:
           async function test() {
             await delay(1000); // 延迟一秒执行 
           }
      
    
    1. async简单介绍
      async彻底解决了异步操作回调函数问题。
      只需使用await关键字,就会等待异步操作执行完毕才会继续执行后续代码。把异步操作
      变为同步操作。
    
      
      // 代码
      async function test() {
          const { data } = await axios.get("http://www.baidu.com"); // { data }为解构赋值
          // do something
      }
      
      // 不用async
      function test() {
          axios.get("http://www.baidu.com").then((res) => {
              console.log(res.data);
              //do something
          });
      }
      
      // 对比以上结构,async函数的同步会带来很大的方便,但在加载网页的时候可能需要等待。
      // 如果不希望页面卡顿,采用异步还是比较好的。
      
    

    2. 每周分享

    1. 前端框架和es的一些变化,这里面介绍的是前端中最近的一些框架或者基础性知识。
    2. nginx的基础入门,对nginx的一个用法基本介绍。
    3. 阿里AI labs研发“智能防骚扰电话技术”,当接听到骚扰电话时,可以转到机器人接听。我试了一下,听得我一愣一愣的,还以为真的和人工客服聊天。具体想体验的可以在支付宝搜索天猫精灵。不过这项功能可能会给你带来困扰,如果你主动挂断电话,就会立马改为由智能机器人接听,如果是你女票打来的,你有事情马上挂断,后果不堪设想!好在可以关闭或者打开。玩玩可以,可不要贪杯啊。(>_<)

    资料

  • 相关阅读:
    什么是 HTTPS
    首页飘雪的效果
    load data导入数据之csv的用法
    phpcms v9 配置sphinx全文索引教程
    js的一些技巧总结
    MySQL 清除表空间碎片
    使用的前台开发在线工具
    (phpQuery)对网站产品信息采集代码的优化
    永远不要打探别人工资
    git 显示多个url地址推送
  • 原文地址:https://www.cnblogs.com/zanzg/p/10566081.html
Copyright © 2020-2023  润新知