资讯专栏INFORMATION COLUMN

Web和Android中的Reactive

liangzai_cool / 2684人阅读

摘要:中的常见写法先看下这段代码。声明式编程,就是告诉机器你想要的是什么,让机器想出如何去做。最独特的特性之一,是其非侵入性的响应式系统。的缩写将遍历此对象所有的属性。这一过程被称为依赖收集。组件的显示,数据的体现大部分都是由承载,传递。

目录

缘起

Android开发中的常见写法

JQuery中的常见写法

命令式编程

声明式编程

React中的常见写法

Vue的常见写法

你肯定熟悉响应式

试着回答

彩蛋

参考

缘起

笔者刚入行的时候,做的是Android客户端开发。虽然从事的时间不长,但稍微了解一点基本的概念。后来阴差阳错从事Web开发,一直到现在,所以现在多多少少对Web领域有一丁点的见解。因为这样,所以有时候会思考下二者的共性,想找一下二者相同的点。最近有两个问题,一直萦绕着:

React中有stateprops的概念。组件component的显示,数据的体现 大部分都是由state承载,props传递。而android基本都是通过setXX去控制组件和数据。为什么会有这样的差异?

同时,redux等状态管理组件都是 flux架构的实现,也有很多开发者提出FluxAndroid的概念,但google官方并不承认flux的架构。这是为什么?

Android开发中的常见写法

我们经常看到这样的写法,首先在xml文件中定义我们的布局文件,指定id等属性。

同时,在Activity中通过findViewById去获取控件的引用,然后进行一系列操作,比如setText

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = (TextView) findViewById(R.id.textview);
        TextView textView = new TextView(this);
        textView.setText("Hey, one more TextView");

    }

除此之外,我们还经常看见这样的写法,比如:

setVisibility(View.VISIBLE);
imageview.setBackgroundColor(Color.rgb(213, 0, 0));

你有没有发现,这些写法有一个共性,就是都是通过setXXX去设定值。也就是说,我们开发者在操作的时候,有这样的一个模式:

获取到值(不管是从数据库还是网络拉取)

这个值经过处理,得到可以目标控件需要的值

通过setXXX去设定该值

然后界面发生变化

后来我发现,这样的模式在JQuery中也是类似的。
JQuery中的常见写法

先看下这段代码。




    learn jQuery



    

例子1

如果你点我,我就会消失。

继续点我!

接着点我!

首先,我们先写了四行HTML代码。
然后,通过JQuery去操作,注意我们的操作方式。

我们通过$("p") 去获取document对象中的

元素,这是不是很像刚刚在上一节提到的findViewById,有木有?

获取到元素后,通过$(this).hide()对该元素进行操作。这像不像 textView.setText("Hey, one more TextView");

如果觉得这段代码不直观,来看这个。




    
    Evan JQery
    
    


这是段落。

这是另一个段落。

Input field:

同时,你可以再本地打开上面的代码,在浏览器中预览,然后打开开发者模式,在控制台中输入,

$("#test3").val("Dolly Ducrrrrk");

你会发现网页内容也随之发生了改变。

命令式编程

维基百科这样说:

Imperative programming is a programming paradigm that uses statements that change a program’s state.

简单理解,命令式编程,就是命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。

上述了两小节都是命令式编程。

声明式编程

提到命令式编程,不得不说下声明式编程。

声明式编程,就是告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。

打个比方:

Declarative Programming is like asking your friend to draw a landscape. You don’t care how they draw it, that’s up to them.
Imperative Programming is like your friend listening to Bob Ross tell them how to paint a landscape. While good ole Bob Ross isn’t exactly commanding, he is giving them step by step directions to get the desired result.

声明式就像你告诉你朋友画一幅画,你不用去管他怎么画的细节

命令式就像按照你的命令,你朋友一步步把画画出来

如果你觉得有点分不清楚二者区别,别着急,先看下下面的案例。

React中的常见写法

(完成源码将放在文末可下载)

"use strict";

const e = React.createElement;

class LikeButton extends React.Component {
  //https://www.cnblogs.com/johnzhu/p/9016277.html
  constructor(props) {
    super(props);
    this.state = { liked: false };
  }

  render() {
    if (this.state.liked) {
      return "You liked this.";
    }

    return e(
      "button",
      { onClick: () => this.setState({ liked: true }) },
      "Like"
    );
  }
}

const domContainer = document.querySelector("#like_button_container");
ReactDOM.render(e(LikeButton), domContainer);

React是声明式的,以上就是体现声明式很好的例子。

在我们的render方法中,渲染一个按钮,按钮名字为“Like”。

按钮的状态(也就是文字内容)受state控制,初始化的state为一个JavaScript对象。

this.state = { liked: false };

点击按钮之后,触发事件,改变state

{ onClick: () => this.setState({ liked: true }) }

好,state在点击前后发生改变,按钮的文字是由state控制。
换句话说,我们并没有直接操作DOM去改变按钮的文字内容,只是通过改变state的状态。
state不同的值描述了按钮在不同情况下应该如何表现不同的内容。

The differences here may be subtle. 
The React example never actually touches an element. it simply declares an element should be rendered given our current state. It does not actually manipulate the DOM itself.

和命令式的区别有点模糊。React没有直接操作元素,它只是声明了元素如何在给定的状态下渲染出特定的结果。

所以,React的思想和JQuery有很大不同。

When writing React, it’s often good not to think of how you want to accomplish a result, but instead what the component should look like in it’s new state.

使用React的时候,最好不同去想着如何实现某个结果,而是组件在新的状态下应该有什么样的表现。

歇一口气 ^ __ ^ 歇一口气

Vue的常见写法

看了React的写法,知道它是声明式,那我们来看看Vue是如何体现响应式的。




    
    VueTest -- evan



    

{{product}} are in stock

我们在模板中指定

{{product}} are in stock

然后再Vue实例中只要product有值,立马就渲染出来。

为了更好的演示,请你打开上述代码,在浏览器中预览,然后打开控制台。输入

app.product = "you input here"

你就会发现屏幕上的网页渲染立马发生了改变。

这就是响应式。

Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。

来我们简单解释下 Vue 响应式系统的底层细节。

第一,还记得我们通过下面的代码,把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项。

           const app = new Vue({
            el: "#app",  /*element的缩写*/
            data: {
                product: "Boots"
            }
        })

Vue 将遍历此对象所有的属性。

第二,Vue使用 Object.defineProperty 把这些属性全部转为 getter/setter。

第三,每个Vue Component的render函数,都都对应一个 watcher 实例。

第四,当 Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这一过程被称为依赖收集)。

第五,data 被改动时(主要是用户操作), 即被写, setter 方法会被调用, 此时 Vue 会去通知所有依赖于此 data 的组件去调用他们的 render 函数进行更新。

你肯定熟悉响应式

还记当时风靡一时的RxJava, RxAndroid嘛?如今又有了RxKotlin,RxDart。(提醒和我一样,做过Android开发的同学们,哈哈~)
他们都是ReactiveX家族的一员。

试着回答
React中有stateprops的概念。组件component的显示,数据的体现 大部分都是由state承载,props传递。而android基本都是通过setXX去控制组件和数据。为什么会有这样的差异?

个人愚见,Android客户端和Web开发中,有这么几点不同:

Android的界面UI是有XML标签定义,和DOM有些不同。

浏览器刷新的时候,整个DOM结构都会更新,而Android没有刷新整个页面的概念,在Android中,你是通过measure (测量)、layout (定位)、draw (绘制)去显示一个View

不同于React中的Component,Android中的View,比如ImageViewTextView 本身内置了很多方法来控制自身属性,比如setBackgroundsetText

(欢迎大佬斧正、补充)

redux等状态管理组件都是 flux架构的实现,也有很多开发者提出FluxAndroid的概念,但google官方并不承认flux的架构。这是为什么?

先简单说明下,Android的架构。

Android架构合集
这篇文章中列举了很多Android架构,包括官方google的,同时也有Flux架构模式。

很多开发者受Flux的启发,写了适用Android的Flux架构模式。
比如下面几篇文章。

AndroidFlux ——当ANDROID遇到了FLUX,架构ANDROID应用的新方式。
Flux Architecture on Android

RxFlux Android Architecture

Flux Android Architecture Components using Kotlin

这个问题我还没有很好的答案。我自己以Flux的架构模式去做过了Android的实践,由于Android Activity等自身的组件,使得用Flux架构反而比较繁琐,有点过度设计的味道。但究竟为何Google官方不推荐,欢迎大家补充~

彩蛋


这就是 Dan 所说的,React 并不是完全的响应式设计的意思。React 需要你手动跟踪应用数据,并在数据变化时告诉 React,这也意味着你得做更多工作。

难道这就是Vue这个响应式框架近几年越来越流行的原因?

放出彩蛋,就是svelte

svelte

哦对了,文中所有的源码在这里哈
点我下载

参考

Imperative programming --维基百科

[Declarative vs Imperative Programming --Ian Mundy
](https://codeburst.io/declarat...

声明式和命令式 --小猪ab

Reactivity in Depth --Vue官方文档

Vue 响应式原理白话版

React 不是真正的响应式编程,Svelte 才是 --Ovie Okeh

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106211.html

相关文章

  • Java Reactive Web设计与实现

    摘要:概念响应式编程,异步非阻塞就是响应式编程,与之相对应的是命令式编程。的另外一种实现方式就是消息队列。非阻塞设计利用规范中的实现实现代码链接 注: 本文是由读者观看小马哥公开课视频过程中的笔记整理而成。更多Spring Framework文章可参看笔者个人github: spring-framework-lesson 。 0. 编程模型与并发模型 Spring 5实现了一部分Reacti...

    siberiawolf 评论0 收藏0
  • Spring Cloud Gateway的全局异常处理

    摘要:中的全局异常处理不能直接用来处理,通过跟踪异常信息的抛出,找到对应的源码,自定义一些处理逻辑来符合业务的需求。如果不做处理,当发生异常时,默认给出的错误信息是页面,不方便前端进行异常处理。需要对异常信息进行处理,返回格式的数据给客户端。 Spring Cloud Gateway中的全局异常处理不能直接用@ControllerAdvice来处理,通过跟踪异常信息的抛出,找到对应的源码,自...

    Lycheeee 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<