Javascript进阶专题总结(函数、异步编程、设计模式)

函数式编程什么时候用

编程方法:函数式(js),面向对象(java,c++),命令式

函数式(工具式操作)

优点:JavaScript种函数是一等公民,便于拆分组合可扩展性好,方便tree-shaking

缺点:管理难度大,复杂逻辑难以组织,模块难以划分

function c1() {
    console.log(1);
}

推荐应用函数式编程:

  • 工具型库 工具库 loadsh underscore 项目重要的基础设置之一
  • 第三方库 造一个库(轮子) 推广出去给很多项目使用 必然会有大量不需要的方法(方便tree-shaking)

工具库组成部分

  • 一些常见的window操作 cookies 内核
  • 一些常见的数据操作
  • 一些业务面常见操作
// 纯函数方法
// window层面操作
export function setCookies() {
    
}
export function getCookies() {
    
}
// 常用数据操作
export function filtersame() {
    
}
// 业务面常见操作
// 例:经常更新token
export function updateToken() {
    
}

面向对象式(具体功能,业务逻辑)

优点:模块分明,逻辑清晰,方便组织庞大业务

缺点:不好配合tree-shaking,JavaScript对于面向对象实现不完美

function class1() {
    
}
class1.prototype.f1 = function () {
    console.log(1);
}

为什么要管理异步(异步目的)

确保执行顺序

异步作为JavaScript的特产,他一定程度上弥补了JavaScript单线程的问题。但是也带来了执行顺序的问题。

所以我们需要确保我们方法得执行按顺序来。此外有的时候我们可能不知道一个操作是同步还是异步。用一个promise绝对不会错。

做异步的一个技巧

  • 先梳理执行顺序,然后再通过异步知识安排执行
  • 回调函数promise化
// 验证
// 1.验证是否是纯数字(同步)
function testNumber() {}
// 2.请求后端,这个数字是否存在(异步)
function back() {}
// 3.请求第三方,验证是否合格(异步)
function other() {}
// 需顺序执行
testNumber();
back();
other();
// 我要做这个事情有哪些步骤,这些步骤有没有异步,
// 要完成这个操作逻辑顺序是什么,然后组织代码按顺序执行
var arr = [testNumber,back,other];
var promise = Promise.resolve();
// 依次执行数组
while(arr.length){
   promise = promise.then(arr.shift()).then(res=>{
        if(res.error) {
            break;        
        }
        return res;    
    })
}
async function run() {
    for(var i=0;i{
    
})
// 回调函数promise化
// nodejs 回调
// 读取一个文件
// 梳理顺序:
// 1.拷贝文件夹read(创建一个readcopy文件夹)
// 2.读取readw文件夹
// 3.循环-》读取一个文件
// 4.写入readcopy
// 原生的回调函数
fs.mkdir("./readcopy", ()=>{
    fs.readdir("./read", (err, context) => {
        context.forEach((file) => {
            fs.readFile("./read/" + file, (err, context) => [
                fs.writeFile("./readcopy/" + file, context, () => {
                                    
                })            
            ])        
        })    
    })
})
// 改写chengpromise
// 先改一个
function readFilePromise(path) {
    return new Promise((resole, reject) => {
        fs.readFile(path,(err, context) => {
            if(err){
                reject(err)            
            } 
            resolve(context);       
        })    
    })
}
// 调用
readFilePromise(path).then((res) => {
    
})
// 当我们面对,需要大量的产出相似对象的时候-》工厂模式
function makePromise(fn) {
    var fn = fn;
    var handle = function (path, data) {
        return new Promise((resolve,reject) => {
           fn.call(this, path, function (err, content) {
               if(err){
                   reject(err)               
               } else {
                   if(data) {
                       resolve(data)                   
                   }else{
                       resolve(content)                   
                   }
               }
           })         
        })    
        return handle;
    }
    return handle;
}
// 使用创建工厂
var dirPromise = makePromise(fs.readdir);
var readFilePromise = makePromise(fs.readFile);
var mkdirPromise = makePromise(fs.mkdir);
var copyDir = function(res){
    res.forEach((file) => {
      readFilePromise("./read/" + file).then((res)=>{
          fs.writeFile("./readcopy/" +file,res,()=>{
                        
          })      
      })  
    })
}
Promise.resolve()
    .then(mkdirPromise.bind(this, "./readcopy"))// bind 绑定参数
    .then(dirPromise(this, "./read"))
    .then(copyDir)
    
async function run() {
    var _result = await mkdirPromise.bind(this, "./readcopy")
    var context = await dirPromise.bind(this, "./read")
    copyDir(context);
}

设计模式分析

如何梳理模块

// 炒菜-》点单 收银-》传菜 服务-》厨师 前台 服务员
// 需求-》 实现这个需求,需要做那些事-》要实现这些事情,应该设计那些模块-》去写这些模块

// 轮播图-》多种播放方式(渐显渐隐,左右切换,上下,百叶窗切换)
// 创建轮播图结构-》开始自动轮播-》播放方式算法-》控制它手动切换
// 轮播图初始化(创建轮播的结构,事件绑定) 轮播控制模块-》 轮播动画效果模块

Javascript进阶专题总结(函数、异步编程、设计模式)_第1张图片

 

轮播图整体类 :可以不用建造者模式(用个单纯的类)

播放效果mover(type): 策略模式

轮播效果模块(异步)-》(告诉第几张)轮播控制模块(观察者模式)

// 请为项目设计一个商品信息缓存器,需求描述如下:
// (1)可根据商品id判断商品是否加载过,如果加载过,直接从缓存里拿;如没有,则请求;
// (2)如果是热门商品,缓存于全局的对象里;
// 如果是非热门商品,则缓存于localStorage中;
// 全局对象和localStorage中的商品数量上限可以配置;
// (3)可主动调用api来更新某个商品的信息。

// maxNum 最多缓存商品数,可以缓存maxNum个热门商品,maxNum个非热门商品
function Goods(maxNum) {
    if(Goods.install){
      return Goods.install;
    }
    this.hotGoods = {}
    localStorage.setItem("noHotGoods", "{}");
    this.maxNum = maxNum || 50;
    Goods.install = this;
}
Goods.install = null;
Goods.prototype.get = async function(id) {
    const goodData = null
    const noHotGoods = JSON.parse(localStorage.getItem("noHotGoods"))
    if (this.hotGoods[id]) {
        return this.hotGoods[id]
    } else if (noHotGoods[id]) {
        return noHotGoods[id]
    } else {
        goodData = await getGoodAjax(id)
        this.set(id, goodData) 
        return goodData
    }
}
Goods.prototype.set = function(id, goodData) {
    /*
    if (goodData.isHot) {// 判断是否是热门商品
        const arr = Object.keys(this.hotGoods);
        if(this.maxNum === arr.length) {
        //    console.log('热门商品缓存已达上限,删除第一个商品')
           delete this.hotGoods[arr[0]]
        }
        this.hotGoods[id] = goodData
    } else {
        const noHotGoods = JSON.parse(localStorage.getItem("noHotGoods"));
        const arr2 = Object.keys(noHotGoods);
        if(this.maxNum === arr2.length) {
        //    console.log('非热门商品缓存已达上限,删除第一个商品')
           delete noHotGoods[arr2[0]]
        }
        noHotGoods[id] = goodData
        localStorage.setItem("noHotGoods", JSON.stringify(noHotGoods));
    }
    */
    let theGood = this.hotGoods;
    if (!goodData.isHot) {
        theGood = JSON.parse(localStorage.getItem("noHotGoods"));
    }
    const arr = Object.keys(theGood);
    if(this.maxNum === arr.length) delete theGood[arr[0]]
    theGood[id] = goodData
    if (goodData.isHot) {
        this.hotGoods = theGood
    } else {
        localStorage.setItem("noHotGoods", JSON.stringify(theGood));
    }
}
var shopGoods = new Goods();
// 获取id=1的商品
var good1 = shopGoods.get(1);
// 更新id=1的商品信息
good1 = shopGoods.set(getGoodAjax(1));

你可能感兴趣的:(Javascript进阶-函数,javascript,设计模式,前端,ecmascript,开发语言)