热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:函数式编程与Js异步编程手写Promise

本文由编程笔记#小编为大家整理,主要介绍了函数式编程与Js异步编程手写Promise相关的知识,希望对你有一定的参考价值。Part1·
本文由编程笔记#小编为大家整理,主要介绍了函数式编程与Js异步编程手写Promise相关的知识,希望对你有一定的参考价值。



Part1 · Javascript【深度剖析】

函数式编程与Js异步编程、手写Promise

文章说明:本专栏内容为本人参加【拉钩大前端高新训练营】的学习笔记以及思考总结,学徒之心,仅为分享。如若有误,请在评论区指出,如果您觉得专栏内容还不错,请点赞、关注、评论。

共同进步!


文章目录




  • Part1 · Javascript【深度剖析】


  • 函数式编程与Js异步编程、手写Promise



    • @[toc]



  • 一、为什么要学习函数式编程


  • 二、什么是函数式编程


  • 三、前置知识



    • 1.函数是一等公民


    • 2.高阶函数



      • 什么是高阶函数


      • 使用高阶函数的意义


      • 常用的高阶函数



    • 3.闭包




一、为什么要学习函数式编程

函数式编程功能是非常古老的一个概念,早于第一台计算机的诞生,函数式编程的历史

学习函数式编程的目的:



  • 函数式编程是随着React的流行受到越来越多的关注;


  • Vue3也开始走入函数式编程的怀抱;


  • 函数式编程可以抛弃this


  • 打包过程中可以更好的利用tree shaking过滤无用的代码


  • 方便测试、方便并行处理


  • 有很多库可以帮助我们进行函数式开发:lodash、underscore、ramda





二、什么是函数式编程

函数式编程(Functional Programming,FP),FP是编程范式之一,常说的编程范式还有面向过程编程、面向对象编程。



  • 【面向对象编程】的思维模式:把现实世界中的失误抽象成程序世界中的类和对象,通过封装、继承和多态来演示事务事件的联系(人类-小明)


  • 【函数式编程】的思维方式:把现实世界的事务和事务之间的联系抽象到程序世界(对运算过程进行抽象)



    • 程序的本质:根据输入通过某种运算获得相应的输出,程序开发过程中会涉及很多有输入和输出的函数


    • x -> f(联系、映射) -> y, y=f(x)


    • 函数式编程中的函数指的不是程序中的函数(或方法),而是数学中的函数即映射关系,例如:y=sin(x),x和y的关系


    • 相同的输入始终得到相同的输出(纯函数)


    • 函数式编程用来描述数据(函数)之间的映射



// 非函数式
let num1 = 2;
let num2 = 3;
let sum = num1 + num2;
console.log(sum);
// 函数式
function add(n1, n2) {
return n1 + n2
}
let sum = add(2, 3);
console.log(sum);



三、前置知识

1.函数是一等公民

MDN First-class Function

在Javascript中函数就是一个普通的对象(可以通过new Function()),我们可以把函数存储到变量、数组中,它还可以作为另一个函数的参数和返回值,甚至我们可以在程序运行的时候通过new Function(‘alert(1)’)来构造一个新的函数



  • 函数可以存储在变量中


  • 函数作为参数


  • 函数作为返回值


  • 把函数赋值给变量


// 把函数赋值给变量
let fn = function () {
console.log('Hello First-class Function')
}
fn() // 函数调用
// 示例
const BlogController = {
index(posts) {return views.index(ports)},
show (post) { return Views.show(post) },
create (attrs) { return Db.create(attrs) },
update (post, attrs) { return Db.update(post, attrs) },
destroy (post) { return Db.destroy(post) }
}
// 示例优化
const BlogController = {
index: Views.index,
show: Views.show,
create: Db.create,
update: Db.update,
destroy: Db.destroy
}


  • 函数是一等公民是后面学习高阶函数、函数柯里化的基础



2.高阶函数


什么是高阶函数



  • 高阶函数(Higher-order Function)



    • 可以把函数作为参数传递给另一个函数


    • 可以把函数作为另一个函数的返回结果



  • 函数作为参数


// 模拟forEach
function forEach(array, fn){
for (let i = 0;i < array.length; i++) {
fn(array[i])
}
}
// 模拟filter
function filter(array, fn) {
let results = [];
for (let i = 0; i < array.length; i++){
if (fn(array[i])) {
results.push(array[i])
}
}
return results;
}


  • 函数作为返回值


function makeFn(){
let msg = 'Hello Function';
return function () {
console.log(msg)
}
}
const fn = makeFn();
fn()

// once模拟支付,业务场景中用户支付次数只允许为一次
function once(fn){
let done = false; // 默认置为false
return function (){
if (!done){
// 若未支付,则进入函数
done = true; // 进入后,将done置为true,确保下次不进入函数
return fn.apply(this, arguments)
}
}
}
let pay = once(function (money)){
console.log('支付:' + money + 'RMB';
}
// 只会打印一次
pay(5);
pay(5);
pay(5);

apply函数提示

apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

注意:call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组

const numbers = [5, 6, 2, 3, 7];
const max = Math.max.apply(null, numbers);
console.log(max);
// expected output: 7
const min = Math.min.apply(null, numbers);
console.log(min);
// expected output: 2
// 详情查看MDN:
// https://developer.mozilla.org/zh-CN/docs/Web/Javascript/Reference/Global_Objects/Function/apply

使用高阶函数的意义




  • 高阶函数是用来抽象通用的问题


// 面向过程的方式
let array = [1, 2, 3, 4];
for (let i = 0; i < array.length;i++) {
console.log(array[i])
}
// 高阶函数
let array = [1, 2, 3, 4];
forEach(array, item) =>{
console.log(item)
}
let r = filter(array, item) =>{
return irem % 2 === 0
}

常用的高阶函数



  • forEach


  • map


  • filter


  • every


  • some


  • find/findIndex


  • reduce


  • sort



// map函数
const map = (array, fn) => {
let results = []
for (const value of array) {
results.push(fn(value))
}
return results
}
// every函数
const every = (array, fn) =>{
let result = true;
for (const value of array) {
result = fn(value);
if (!result) {
break
}
}
return result
}
// some函数
const some = (array, fn) =>{
let result = false;
for (conse value of array) {
result = fn(value);
if (result) {
break
}
}
return result
}

3.闭包



  • 闭包(Closure):函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包。

    // 函数作为返回值
    function makeFn() {
    let msg = 'Hello Function';
    return function () {
    console.log(msg)
    }
    }
    const fn = makeFn();
    fn()
    // once
    function once(fn) {
    let done = false;
    return function (){
    if (!done) {
    return fn.apply(this, arguments)
    }
    }
    }
    let pay = once(function (money) {
    console.log('支付:' + money + 'RMB')
    })
    // 只会支付一次
    pay(5);
    pay(5);



    • 可以在另一个作用域中调用一个函数的内部函数并访问到高函数的作用域中的成员



  • 闭包的本质:函数在执行的时候会放到一个执行栈上,当函数执行完毕后会从执行栈上移出,但是堆上的作用域成员因为被外部引用不能释放,因此内部函数依然可以访问外部函数的成员


  • 闭包案例


// 生成计算数字多少次幂的函数
function makePower(power) {
return function (x) {
return Matn.pow(x, power)
}
}
let power2 = makePower(2);
let power3 = makePower(3);
console.log(power2(4))
console.log(power3(4))
// 第一个函数是基本工资,第二个函数是绩效工资
function makeSalary(x) {
return function (y) {
return x + y
}
}
let salaryLevel1 = makeSalary(1500);
let salaryLevel2 = makeSalary(2000);
console.log(alaryLevel1(2000))
console.log(alaryLevel1(3000))

今日分享截止到这里,明天继续更新后续部分:纯函数、柯里化、函数组合、Functor。

记录:2020/11/14



推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 本文介绍了腾讯最近开源的BERT推理模型TurboTransformers,该模型在推理速度上比PyTorch快1~4倍。TurboTransformers采用了分层设计的思想,通过简化问题和加速开发,实现了快速推理能力。同时,文章还探讨了PyTorch在中间层延迟和深度神经网络中存在的问题,并提出了合并计算的解决方案。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • Learning to Paint with Model-based Deep Reinforcement Learning
    本文介绍了一种基于模型的深度强化学习方法,通过结合神经渲染器,教机器像人类画家一样进行绘画。该方法能够生成笔画的坐标点、半径、透明度、颜色值等,以生成类似于给定目标图像的绘画。文章还讨论了该方法面临的挑战,包括绘制纹理丰富的图像等。通过对比实验的结果,作者证明了基于模型的深度强化学习方法相对于基于模型的DDPG和模型无关的DDPG方法的优势。该研究对于深度强化学习在绘画领域的应用具有重要意义。 ... [详细]
  • 本文介绍了200个经典c语言源代码,包括函数的使用,如sqrt函数、clanguagefunct等。这些源代码可以帮助读者更好地理解c语言的编程方法,并提供了实际应用的示例。 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
author-avatar
偶们滴小圈子6868
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有