React 监听页面滚动,界面动态显示

当页面滚动时,如何动态切换布局/样式

1. 添加滚动事件的监听/注销

//在componentDidMount,进行scroll事件的注册,绑定一个函数,让这个函数进行监听处理
componentDidMount() {
window.addEventListener('scroll', this.bindHandleScroll)
}
//在componentWillUnmount,进行scroll事件的注销
componentWillUnmount() {
window.removeEventListener('scroll', this.bindHandleScroll);
}
bindHandleScroll = (event) => {

}

2. 在state中添加参数,滚动页面时更新数据

更新参数后,设置样式。可以直接更新样式,也可以动态修改className然后在css文件中添加动态样式。

bindHandleScroll = (event) => {
// 滚动的高度
const scrollTop = (event.srcElement ? event.srcElement.documentElement.scrollTop : false)
|| window.pageYOffset
|| (event.srcElement ? event.srcElement.body.scrollTop : 0);
this.setState({
hasVerticalScrolled: scrollTop > 10
})
}
render() {
return (
<div className="header-container" style={{backgroundColor:this.state.hasVerticalScrolled?'#ffffff':'transparent'}}>
<div className="headerTitle-container">
<img className={`headerTitle${this.state.hasVerticalScrolled ? '-scrolled' : ''}`}></img>
</div>
</div>
);
}

完整Code: 

import react, { Component } from 'react';
import './style.less';

interface PropsData {
}
interface StateData {
hasVerticalScrolled: boolean;
}

class Index extends Component<PropsData, StateData> {
constructor(props) {
super(props);
this.state = {
hasVerticalScrolled: false
};
}

//在componentDidMount,进行scroll事件的注册,绑定一个函数,让这个函数进行监听处理
componentDidMount() {
window.addEventListener('scroll', this.bindHandleScroll)
}
//在componentWillUnmount,进行scroll事件的注销
componentWillUnmount() {
window.removeEventListener('scroll', this.bindHandleScroll);
}
bindHandleScroll = (event) => {
// 滚动的高度
const scrollTop = (event.srcElement ? event.srcElement.documentElement.scrollTop : false)
|| window.pageYOffset
|| (event.srcElement ? event.srcElement.body.scrollTop : 0);
this.setState({
hasVerticalScrolled: scrollTop > 10
})
}
render() {
return (
<div className="header-container" style={{backgroundColor:this.state.hasVerticalScrolled?'#ffffff':'transparent'}}>
<div className="headerTitle-container">
<img className={`headerTitle${this.state.hasVerticalScrolled ? '-scrolled' : ''}`}></img>
</div>
</div>
);
}
}

export default Index;

作者:唐宋元明清2188 出处:http://www.cnblogs.com/kybs0/

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/9303

canvas的getImageData和toDataUrl跨域问题

背景是这样的,母亲节的时候,我们有个需求就是用户可以长按或者点击一个按钮进行截图后去分享我们的活动,然而我们的图片例如头像,采用又拍云做 cdn 优化,所以意味着图片的链接跟主页面所在域名不一样,当需要需要对 canvas 图片进行 getImageData() 或 toDataURL() 操作的时候,跨域问题就出来了。

对于跨域的图片,只要能够在网页中正常显示出来,就可以使用 canvas 的 drawImage() API 绘制出来。但是如果你想更进一步,通过 getImageData() 方法获取图片的完整的像素信息,则多半会出错。

举例来说,使用下面代码获取 github 上的自己头像图片信息:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

结果在 Chrome 浏览器下显示如下错误:

Uncaught DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.

Firefox 浏览器错误为:

SecurityError: The operation is insecure.

如果使用的是 canvas.toDataURL()方法,则会报:

Failed to execute ‘toDataURL’ on ’htmlCanvasElement’: Tainted canvased may not be exported

原因其实都是一样的,跨域导致。

那有没有什么办法可以解决这个问题呢?

可以试试 crossOrigin 属性。

html crossOrigin 属性解决资源跨域问题

在 html5 中,有些元素提供了支持 CORS(Cross-Origin Resource Sharing)(跨域资源共享)的属性,这些元素包括 ,,“ 等,而提供的属性名就是 crossOrigin 属性。

因此,上面的跨域问题可以这么处理:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.crossOrigin = '';
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

增加一个 img.crossOrigin = ” 即可,虽然 js 代码这里设置的是空字符串,实际上起作用的属性值是 anonymous。

crossOrigin 可以有下面两个值:

关键字 释义
anonymous 元素的跨域资源请求不需要凭证标志设置。
use-credentials 元素的跨域资源请求需要凭证标志设置,意味着该请求需要提供凭证。

其中,只要 crossOrigin 的属性值不是 use-credentials,全部都会解析为 anonymous,包括空字符串,包括类似 ‘abc’ 这样的字符。

例如:

img.crossOrigin = 'abc';
console.log(img.crossOrigin);    // 结果是'anonymous'

另外还有一点需要注意,那就是虽然没有 crossOrigin 属性,和设置 crossOrigin=”use-credentials” 在默认情况下都会报跨域出错,但是性质上却不一样,两者有较大区别。

crossOrigin 兼容性

IE11+(IE Edge),Safari,Chrome,Firefox 浏览器均支持,IE9 和 IE10 会报 SecurityError 安全错误,如下截图:

crossOrigin 属性为什么可以解决资源跨域问题?

crossOrigin=anonymous 相对于告诉对方服务器,你不需要带任何非匿名信息过来。例如 cookie,因此,当前浏览器肯定是安全的。

就好比你要去别人家里拿一件衣服,crossOrigin=anonymous 相对于告诉对方,我只要衣服,其他都不要。如果不说,可能对方在衣服里放个窃听的工具什么的,就不安全了,浏览器就会阻止。

下载到本地

IE10 浏览器不支持 crossOrigin 怎么办?

我们请求图片的时候,不是直接通过 new Image(),而是借助 ajax 和 URL.createObjectURL() 方法曲线救国。

代码如下:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    var url = URL.createObjectURL(this.response);
    var img = new Image();
    img.onload = function () {
        // 此时你就可以使用canvas对img为所欲为了
        // ... code ...
        // 图片用完后记得释放内存
        URL.revokeObjectURL(url);
    };
    img.src = url;
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();

此方法不仅 IE10 浏览器 OK,原本支持 crossOrigin 的诸位浏览器也是支持的。

也就多走一个 ajax 请求,还可以!

根据,根据实践发现,在 IE 浏览器下,如果请求的图片过大,几千像素那种,图片会加载失败,我猜是超过了 blob 尺寸限制。

后来采用的解决方案是:把图片下载到本地(前端或者是后端都可以,最后采用我前端来做)

    getAvator(user, func) {
      window.URL = window.URL || window.webkitURL;  // Take care of vendor prefixes.
      var xhr = new XMLHttpRequest();
      xhr.open('GET', user.avatar, true);
      xhr.responseType = 'blob';
      xhr.send()

      xhr.onload = function(e) {
        const {target} = e
        const {status, response, readyState} = target
        if (readyState == 4 && status == 200) {
          var blob = response;
          var img = document.createElement('img');
          img.classList.add("avatar")
          var reader = new window.FileReader();
          reader.readAsDataURL(blob);
          reader.onloadend = function() {
            var base64data = reader.result;
            img.src = base64data;
          };
          func && func(img)
        }
      };
    },

设置 nginx 代理

如 php 添加响应头信息,* 通配符表示允许任意域名:

header("Access-Control-Allow-Origin: *");

或者指定域名:

header("Access-Control-Allow-Origin: www.zhangxinxu.com");

html2canvas 真实采坑记和建议

如果使用 vue 做数据渲染,不要在生成页做太多数据处理的操作,提前把动态数据处理好,否则即便用 $nextTick 也会有在生成图片时数据不完整的情况

引用 CDN 上的图片,需要设置 useCORS 为 true,同时要保证所有图片加载完成后再生成,可使用 new Imaage 做预加载和判断是否全部 load

用背景 background,生成的图片清晰度不够,会模糊;用 img 引入的方式可避免这个问题

在 iOS 系统的 13.4.1,无法生成图片,需要退回到 1.0.0-rc.4 版本,不要使用 1.0.0-rc.5 版本,issues 地址:https://github.com/niklasvh/html2canvas/issues/2205

可把生成的图片设置透明度 opacity 为 0,盖在原有元素之上,便于在微信保存,不会因为生成的图和原有元素略微有差距,而抖动。

来自:https://www.cnblogs.com/Jomsou/archive/2020/07/18/13334741.html

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/9480

JS高阶函数reduce()的常用场景

1. reduce()语法

// total	必需。初始值, 或者计算结束后的返回值。
// currentValue	必需。当前元素
// currentIndex	可选。当前元素的索引
// arr	可选。当前元素所属的数组对象。
// initialValue	可选。传递给函数的初始值
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

2. 数组求和

var aa = [1,2,3,4.1,5,'2','9'];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
    return total+ Number(currentValue)
},0)
console.log(bb); // 26.1

3. 数组最大值

var aa = [1,2,3,4.1,5,'2','9'];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
    return Math.max(Number(total),Number(currentValue))
})
console.log(bb); // 9

4. 数组去重

var aa =[1,2,3,4.1,5,5,'2','2','9',1];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
    if(total.indexOf(currentValue) == -1) {
	    total.push(currentValue);
	}
	return total;
},[])
console.log(bb); //  [1, 2, 3, 4.1, 5, "2", "9"]

5. 计算数组中每个元素的出现的次数

var aa = [1,2,3,4.1,5,5,2,2,9,1];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
   total[currentValue]?total[currentValue]++:total[currentValue]=1
   return total
},{})
console.log(bb);// {1: 2, 2: 3, 3: 1, 5: 2, 9: 1, 4.1: 1}


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/9530

JavaScript 疲劳终极指南:我们行业的真相

抱怨 JS 疲劳就像是在抱怨人类发明了太多解决问题的工具:从邮件到飞机到宇宙飞船。

上周我在 NebraskaJS 2017 会议上做了一个和这个话题极其类似的演讲,我也收到了许多积极的反馈,所以我就想这个演讲也可以写成一篇文章发表出来,让更多的人知道,并帮助他们应对 JS 疲劳,理解我们行业的真相。这篇文章的目的是希望改变你对软件工程行业的普遍的看法,助你在你可能工作的领域上一臂之力

激励我写下这篇文章并且彻底改变我生活的一个原因是 Patrick McKenzie 写的这篇很赞的文章,文章名叫《请不要自称程序员和一些职业生涯建议》强烈推荐你阅读下上面这篇文章。本文的大部分内容都是基于 Patrick 的那篇关于 JavaScript 生态系统的文章的建议,其中也夹杂了最近几年我在科技行业工作的一些想法。

第一个章节可能会有点哲学化,但是我保证绝对值得一读。

我们行业的真相 101

就像 Patrick 在 他的文章 里写到的,我们先从一些最基础、最根本的真相说起:

软件是用来解决业务问题的

实事就是这样。软件存在的意义并不是用来取悦我们程序员的,并不是为了让我们写出漂亮代码的,也不是为科技行业创造就业机会的。实际上,软件的存在扼杀了太多的工作岗位,其中也包括我们的,这就是为什么基本工资在未来的几年将会变得更加重要,但是这就完全是另一个话题了。

我这样说很抱歉,但是归根结底原因在于:在软件工程中(其他行业也是如此)只有两样东西至关重要:

支出和收益

支出削减的越多,收益提升的越多,那么你的价值就越大,削减支出、提升收益最通用的一个方法就是用机器代替人工,从长远来看,这种方法是更有效的,而且支出也更少。

你不是被雇佣来写代码的

科技不是目的。没有人关心你使用的是什么编程语言,没有人关心你的团队选择的是什么框架,没有人关心你的数据结构有多么优雅,也没有人关心你的代码写得有多漂亮。人们唯一关心的是:你的软件支出是多少,产生的收益是多少,仅此而已

写出漂亮的代码对于你的客户而言没有任何卵用。我们之所以要写漂亮的代码,是因为长远来看这样会更高效,能够减少支出,增加收益。

我们努力避免 bug 不是说我们重视正确性,而是我们的客户重视正确性。如果你曾经遇到过一个 bug 成为了一个特性的话,那么你就知道我在说什么了。这个 bug 确实存在,但是我们不会去修复。出现这种情况并不是说我们的目的就是制造 bug,我们的目的是创造价值。但是如果我们的 bug 能够使客户开心,能够提升他们的收益,我们也能达成我们的目标,如此皆大欢喜,何乐而不为呢。

可重复使用的太空火箭、自动驾驶汽车、机器人、AI:这些东西之所以存在,并不是因为我们觉得它们很酷,而是因为在它们的背后有商业利益存在。我并不是说这些东西背后的那群人只在乎金钱,我确定他们也认为这东西很酷,但事实是,如果没有经济利益或者说没有潜在的经济价值,这些东西是不会存在的。

也许我不应该将这一章节取名为“我们行业的真相 101”,也许应该取名为“资本主义真相 101”。

说到我们的目标——减少支出提升收益——我认为作为程序员的我们应该更加关注需求和设计,积极思考,积极参与业务决策,这就是为什么了解我们正在开展的问题领域变得极其重要。之前你有多少次在你的经理或商务人士没有考虑到的某些边缘案例中想到应该发生什么?

1975 年,Boehm 做过一项研究,研究发现,软件中 64% 的错误都是由设计引起的,只有 36% 的错误是代码错误。另一项叫做 “高阶软件——软件定义方法论” 的研究也显示:在 NASA 的阿波罗计划中,73% 的错误都是设计错误

设计和需求存在的唯一目的就是定义我们将要解决的问题,而解决问题就能创造收益。

没有了需求或设计,编程就是往一个空的 text 文件里面添加 bug。

  • Louis Srygley

这个原则同样适用于 JavaScript 生态系统的工具。Babel、webpack、react、Redux、Mocha、Chai、Typescript,所有这些工具之所以存在就是为了解决对应的问题,我们要理解它们要解决的是什么问题,要仔细思考什么时候需要这些工具,否则,我们就会感到 JS 疲劳,因为:

当我们使用我们不需要的工具来解决根本就不存在的问题的时候,JS 疲劳就出现了。

正如 Donald Knuth 曾今说的:“过早优化是万恶之源”。请记着,软件的存在是为了解决相应的业务问题,大部分的软件其实都挺令人厌烦的,既没有多强的扩展性,也没有高性能约束。要专注于解决业务问题,专注于减少支出、提升收益,这才是需要关注的焦点。只有在当你需要优化的时候才去优化,否则,软件可能会增加一些不必要的复杂性,而这些复杂性会增加支出,并且不能产生足够的收益来抵消这些支出。

这就是为什么我认为应该在我们的工作当中应用 测试驱动开发 原则。我说的测试驱动开发并不是说仅仅去做测试。我说的是在问题暴露之前将其扼杀在摇篮里。这才是 TDD 要做的。正如 Kent Beck 说的“TDD 减少了恐惧”,因为它能够指导你的开发节奏,允许你慢慢地逐步解决你的问题,一步一个脚印,一次解决一个问题。当我们要使用新的技术时,这样做同样也会减少恐惧。

一次解决一个问题同时也降低了 分析麻痹,举个栗子,就好比你打开了 Netflix,你本可以看一些视频的,但是却花了三个小时来决定看什么。一次解决一个问题的方式可以缩小我们做决定的范围,缩小了做决定的范围我们的选择就会相对减少,选择减少了我们就降低了分析麻痹。

不知道你有木有想过,如果只有几个可看的电视频道,决定看哪个频道会变得多么简单?如果家里只有几张游戏盘,决定玩儿哪个游戏会变得多么简单?

那么对于 JavaScript 而言呢?

截止到我写这篇文章时,NPM 上有 489,989 个包,第二天将会有差不多 515 个包在上面发布。

我们使用、抱怨的这些包都是有一个历史出发点的的,为了理解我们为什么需要这些包,我们必须理解这个历史出发点:它们是用来解决问题的。

Babel、Dart、CoffeeScript 和其他转义器之所以会出现,是因为我们不仅仅使用 JavaScript 写代码,但是我们又想使其能够在浏览器中正常运行。Babel 甚至能够使我们使用 JavaScript 新版本语法写的代码在旧版本浏览器中运行,因为众所周知,不同版本的 ECMA 规范在各个浏览器中的兼容是一个很大的问题。尽管现在 ECMA 规范已经越来越可靠,但是我们仍然需要 Babel。如果你想了解更多关于 Babel 的相关知识,我强烈推荐你读读 这篇由 Henry Zhu 写的很赞的文章

像 Webpack 和 Browserify 这样的模块化打包工具也有它们存在的理由。想必你们依然记得,曾几何时,我们使用大量的 script 标签将脚本引入使其能够正常运行。这样做的结果就是污染了全局命名空间,当一个脚本依赖另一个脚本时,很难合理地将它们整合起来。为了解决这个问题,Require.js诞生了,但是它仍然有它自己的问题:它不够简单,语法也会引起其他问题,正如你在这篇文章中看到的。然后 Node.js 借鉴了 CommonJS 的 import,这种 import 是同步的,简单整洁,但是我们仍然需要一种可以在浏览器中运行的方式,这就是为什么我们需要 Webpack 和 Browserify 的原因。

Webpack 确实解决了很多问题,比如可以像处理 JavaScript 依赖那样处理 CSS、图片和许多其他的资源。

前端框架确实有点复杂,但是由于它们的存在,使得我们写代码时减少了同步加载,如此一来,我们就不必担心 DOM 操作,甚至也不用和那些乱七八糟的浏览器 API(JQuery 已经解决了这个问题)直接打交道,众所周知,浏览器的兼容性处理错误百出,而且效率低下。

这就是我们在计算机科学中一直在做的事情。我们使用低级抽象,并在其上构建更多的抽象。我们应该更多考虑的是,我们的软件应该如何运行,而不是怎么让它运行,这样的话,才能更高效。

但是所有这些工具都有一个共同之处:它们之所以存在是因为 web 平台发展太快了。如今任何地方都有 web 技术的存在:web 浏览器,桌面应用,电话应用,甚至手表应用。

这个革命性发展同样也暴露出了我们需要解决的问题。比如,渐进式 web 应用(PWA),它们之所以存在不是因为它们很炫酷,不是因为作为程序员的我们乐于写 PWA。请牢记本文的第一节:PWA 之所以存在,是因为它们创造了商业价值

通常情况下,标准的制定速度并没有那么快,因此,针对对应的问题我们需要自己寻求解决方法,这就是为什么有一个活跃度高、有创造力的社区是一件很 nice 的事情。我们不是在解决问题,就是在去解决问题的路上。当然,我们也会顺其自然

适用于我们的工具会更好地成长,获得更多的贡献者,更快地发展,有时一些工具最终将融合来自于其他工具的优秀想法,并且变得比它们更受欢迎。这就是我们演变的进程。

拥有越多的工具,我们就会拥有越多的选择。想必你还记着 UNIX 思想,它主张我们在编程时,一次只做一件事情,而且要将它做到极致。

我们可以清晰的看到这种思想在 JS 测试环境中重现,比如,我们使用 Mocha 跑测试,使用 Chai 做断言,而在 Java 中,JUnit 把这些事情全部包揽了。这就意味着,如果你在使用某一个工具的过程中遇到了问题,并且发现另一个工具更适合我们的话,那么我们就可以直接简单的替换掉之前的工具就可以了,其他工具的优势我们依然能够保留。

UNIX 思想同时主张我们应该去写能够“和谐相处”的程序。这正是我们在做的!比如说 Babel、Webpack 和 React。同时使用它们完全能够正常运行,但是我们并不需要使用一个工具而去依赖另一个工具。比如我们在测试环境中使用 Mocha 和 Chai,那么我们也可以安装 Karma 在多种环境中来跑同样的测试。

如何应对

针对正在遭受 JS 疲劳的同学,我的第一个建议是:你要清醒的认识到你并不需要掌握所有东西。有时我们会一次性学习过多的知识——甚至当我们并不需要的时候,这样做只会增加疲劳感。你喜欢的领域你要保持积极的学习动力,可以深入了解,而对于其他的知识,你大可保持慵懒的态度。我这里说的慵懒不是让你懒惰,而是在你需要某些知识的时候再去学习。当你遇到了问题,且需要使用某项知识技能来解决的时候,直接现学就可以了。

另一个重要的建议是:脚踏实地,从头开始。在你使用任何 JavaScript 框架之前,请确保你对原生 JavaScript 学习的已经足够透彻。这是你掌握 JavaScript 并能够将其“玩弄于鼓掌之中”的唯一途径,否则,当你遇到了你之前从来没有见过的问题时,你就不知道该如何下手。学习核心的 web 技术——CSS、HTML5、JavaScript和计算机科学基础,甚至是 HTTP 协议的工作原理——将会有助于你快速掌握任何其他的技术。

但是,请务必不要用力过度。偶尔你要挑战一下自己,亲自动手做一些项目。正如 Sacha Greif 在这篇文章里写到的那样:花费过多的时间学习基础知识就像你要学习游泳时总是在学习流体动力学。学到一定程度以后,你就应该跳到游泳池里去尝试游泳。

同时,请务必不要拘泥于一项技能。我们现在可用的技术其实在过去都早已被发明出来了。当然,它们特性不同,名字不同,但是,本质上它们都是相同的。

如果你看看 NPM 的话,它也不是什么新技术,很早之前就有 Maven Central 和 Ruby Gems 了。

用来转义代码的 Babel,也是借鉴了早期一些非常出名的编译器的原则和理论,比如 GCC。

甚至 JSX 也不是什么新想法。E4X(ECMAScript for XML)10 多年前就存在了。

那么现在你可能会问:“那 Gulp、Grunt 和 NPM 脚本又如何呢?”额,好吧,很遗憾的告诉你,这些问题 GNU Make 在 1976 年都已经解决了。实际上,现在仍然有大量的 JavaScript 工程在使用 GNU Make,比如 Chai.js。但是我们不会那样做,因为我们是喜欢复古的潮人。我们使用 make,因为它解决了我们的问题,正如我们之前讨论过,这就是你的目标所在。

如果你真的想要理解某项技术,想要在面对任何问题时都能够得心应手,那么,请深入了解。成功最关键的一个因素就是好奇心,所以请深入了解你喜欢的技术。尝试自下而上的理解它们,每当你认为某些东西如“魔法”一般时,那么请通过探索代码库来揭开它的神秘面纱。

在我看来,说到学习这块儿,Richard Feinman 的这句名言最适合不过了:

我创造不了的东西,我理解不了

再来看看下面这句,这是 Richard 在同样的一块儿黑板上写下的

对于已经存在答案的问题要知道如何解决

是不是很赞?

当 Richard 说这些话的时候,他正在讨论的是关于获取理论结果并如何复现的问题,但是我认为,该原则同样适用于软件工程。能够解决我们的问题的这些工具已经被发明出来了,它们已经存在了,所以我们也应该能够自己来实现它们。

这正是我喜欢 Egghead.io 中一些视频的原因,视频中 Dan Abramov 解释了如何从头开始实现 Redux 中存在的某些功能,或者教你如何构建自己的 JSX 渲染器

那么我们为什么不去尝试着自己来实现或者去 GitHub 上阅读代码库理解它们的原理来实现这些东西呢?我确定你一定能够发现很多有用的知识。评论和 demo 也许会撒谎,也许会误导,但是代码不会。

另一个我们在这篇文章中谈论的最多的话题是:你不应该超前你自己。遵循 TDD 原则,一次只解决一个问题。你被雇佣是来降低成本提升收益的,你所做的都是为了解决问题,这就是软件存在的意义。

既然我们喜欢拿我们自身的角色和土木工程相关的作对比,那么就让我们快速对比下软件开发和土木工程,就像Sam Newman 在《构建微服》中做的那样

我们喜欢自称“工程师”或“架构师”,但是这样真的好么?我们一直在为不到一百年前的计算机开发我们所知的计算机软件,而竞技场都存在大约两千年了。

还记得最近一次看到一座桥坍塌是什么时候吗?还记得最近一次你的手机或浏览器奔溃是什么时候吗?

为了更好的解释,我借用一个我比较喜欢的栗子。

这是美丽惊艳的巴塞罗那。

当我们从这个距离看这座城市的话,它开起来和世界上的其他城市一般无二,但是当我们从上面俯瞰时,巴塞罗那看起来是这个样子的:

正如你看到的,每一个块儿都有着相同的尺寸,所有的块儿都有条不紊的排列着。如果你曾经去过巴塞罗那的话,你一定知道穿越这座城市有多么爽,知道它运行的多么良好。

但是坐在飞机上俯瞰巴塞罗那的人无法预知两百年或者三百年后它会成为什么样子。城市里的人们进进出出,他们要做的是让城市随着时间的流逝有机地成长、适应。他们必须做好应对变化的准备。

同样的事情也发生在软件方面。软件更新迭代很快,会经常需要重构,需求也会频繁的变更,这完全在我们的预期之外。

所以,不要把自己当做软件工程师,要把自己当做城市规划者。让你的软件有机成长,按需适应。兵来将挡,水来土掩,问题来了就去解决,但是要确保一切都有其所在。

在软件领域做这些事情比在城市里做这些事情要容易的多,因为软件是灵活的,土木工程并不是在软件世界里,我们的“建筑时长”就是编译时长。在巴塞罗那我们不能通过简单地毁掉建筑给新的建筑腾出空地儿,但是在软件世界里我们可以非常简单的实现。我们随时可以推翻重做,随时可以做实验,我们想构建几次就构建几次,时间花费也就那么几秒钟,但是我们思考的时间却比构建的要多得多。我们的工作是纯智力型的。

所以把自己当做城市规划者,让你的软件按需成长、适应

通过这样做,你就能够更好的抽象,也会知道在什么合适的时间来采用它们。

正如 Sam Koblenski 所说:

抽象只适用于合适的语境,而合适的语境是随着系统的发展而发展的。

有时候我经常会看到这种现象:有些同学在学习一项新技术时会去寻找模板,但是在我看来,当你开始学习的时候,应当避免使用模板。当然,如果你已经有了一定经验,那么模板和生成器还是很有用的。模板剥夺了大部分的控制权,因此你就学不到如何去新建一个工程,你也无法准确理解每个代码片段适合哪里。

当你无法轻轻松松地把事情搞定,当你感受到的都是苦苦的挣扎时,也许是时候另辟蹊径了。我们的宗旨是力争懒惰,你应该为了以后不工作的目标而去工作。如此一来,你就会有更多的自由时间去做其他的事情,从而减低了成本,提升了收益,所以这也是你达成目的的另一条途径。你不应该没头没脑的努力工作,你要更加聪明的工作。

也许有些人也会拥有你现在的烦恼,但是如果没人这样做的话,那么你的机会就到了,你可以找到你自己的解决方法,可以给其他人伸出援助之手。

但是有时候在你没有看到别人做的更优秀之前,你并不会意识到其实你也可以做的更高效。这就是与人交流的重要性。

通过和其他人交流,你可以分享你的经验,为对方的职业生涯提供帮助,也能发现能够提升我们工作流的新工具,而且更重要的是,你能够学到解决问题的方法。这就是我喜欢阅读分享公司解决问题方法的文章的原因。

尤其是在我们的领域里,我们总是认为 Google 和 StackOverflow 能够回答我们的所有问题,但是我们仍然有必要知道我们要问的问题。我确定会有这么一种场景:你遇到了一个你无法解决的问题,因为你无法准确的知道发生了什么事情,所以你自己都不清楚你应该问什么问题。

但是如果我需要用一个建议来总结整篇文章的话,那就是:

解决问题。

软件不是魔法箱,也不是一首诗(很不幸)。它的存在是为了解决问题,提高人们的生活水平。软件的存在是为了让世界向前发展。

年轻人,该你出动解决问题了

在对城市进行沐鸣平台数字化改造时,物联网开发商面临着关键问题

毫无疑问,数字化的智能城市是未来的潮流。但是通往一个更加紧密联系的市政当局的道路还很不明朗。尽管在美国的主要大都市地区有一些共同的挑战,没有两个城市拥有相同的基础设施、治理、态度、预算或需求。芝加哥的处事方式与达拉斯、亚特兰大或旧金山的处事方式不同。沐鸣平台

围绕着通过数字化转型建设智慧城市,有很多问题。发展的首要解决方案是什么?谁是真正的客户?这些数据会发生什么?这些答案将决定二十年后的世界面貌。它看起来肯定会和现在很不一样。

首先,考虑为使城市更加友好而提出的各种数字转换。爱立信网络和技术战略主管鲍勃•格塞尔(Bob Gessel)证实,最初的实施将取决于这座城市以及他们试图解决的问题。爱立信押注交通运输将成为许多城市的领跑者。“我们花时间了解交通和流动性,以帮助城市管理现有和未来的交通。其目标是测量基础设施并向用户提供数据,以便他们能够基于态势感知更好地导航。我们称之为互联流量云。该公司希望帮助城市和通勤者找到新的方法,将数据处理成节省时间、燃料和能源的新见解。

智能汽车、建筑和城市将同时出现

除了与制造商在车辆内的仪表方面合作,物联网创新者还关注车辆对车辆和车辆对基础设施的通信。事实上,智能汽车更有可能在智能城市中激增。Bob表示,联网的城市将为自动和半自动汽车生成新的数据。“这样就有可能确定他们将在哪里开车,并在安全区域进行测试。”沐鸣总代理

事实上,打个比方,公路可能很快就会被物联网堵塞。在任何智能交通解决方案中,自动报告道路状况的车辆都将发挥关键作用。当旧的路边灯被LED灯取代时,新的灯可能还包含空气质量传感器。来自这些边缘设备的数据可以为居民和游客提供提前通知,他们可能需要调整旅行计划、户外活动和药物,以应对环境威胁。

在启动阶段,一些解决方案专注于解决终端用户层次上的特定问题。在最近的北德克萨斯物联网黑客松(North Texas IoT hackathon)上,智慧城市和联网汽车是创新的重要领域。Yeshvik Solutions的校长Yeshwant Muthusamy博士提出了一个物联网系统,该系统将使在大学停车场和车库内停车更容易、更安全。其他创新公司的目标是为游客和新居民提供交互式电视或智能手机应用,以促进基于地理空间定位的当地活动和商业活动。沐鸣登陆地址

数字化转型为智慧城市

Yeshwant指出,美国并没有在向互联城市转变的道路上走在前面,但人们的态度正在转变。“智能城市已经在美国以外的地方流行起来,我认为它正在发生变化,并开始在美国表现出来。“这种延迟的一个原因是,买进可能是一个挑战。有许多利益攸关者参与其中,包括市议会、公共机构的民选官员、商业领袖和其他感兴趣的政党。“提出解决方案的人有责任识别客户,并就节约成本或创收的结果进行沟通。”你必须迎合关键的方面。碰撞村首席执行官、黑客松组织者Tahir Hussain表示同意。“利益相关者是城市,但客户是看到愿景和价值的人。”

敏捷和DevOps沐鸣测速注册并不是软件开发中神奇的独角兽

TechRepublic上有一篇名为《DevOps实施的十大挑战》的文章(链接如下)。那么挑战是什么呢?他们列出了标准的东西,比如文化和技能,计划和工具。沐鸣测速注册

如果不是因为我写的或发表的关于类似主题的文章比我愿意承认的要多,我会批评这个列表的愚蠢。我记得有三个月的时间,我被要求收集关于如何让DevOps工作的不同见解,我写的每一篇关于这个主题的文章似乎都集中在文化、技能和计划上,而文化总是占据了大部分的焦点。这里只是几个例子:

协作和社区是DevOps在2017年取得成功的关键

通过DevOps过渡的三个最艰难的阶段

应用生命周期管理需要统一的DevOps方法

这个问题比DevOps转换更根本

这是我对这类文章的看法。一个组织缺乏技能、计划和适当的工具不会导致DevOps采用失败。这些东西的缺乏是导致组织失败的原因。当人们谈论“文化”时,他们谈论的是一种普遍的心态。如果你的IT部门是由一群人组成的,他们向不同的方向推进,那么问题不在于采用DevOps,而在于整个IT部门。沐鸣怎么当代理?

我一直认为,切换到DevOps之所以有效,与敏捷的原因是一样的,而这与方法本身无关。转向DevOps或敏捷的原因是,它让部门没有做测试,没有做质量控制,没有雇佣正确的人,没有使用正确的工具来开始正确地做所有这些事情。如果那些混乱的组织将所有这些事情付诸行动,但是保持开发和操作之间的障碍,他们可能会看到所有相同的好处,如果他们做了所有这些事情,但是坚持瀑布式开发方法,他们也会看到进展。

必须有一个方法

我不是那种到处鼓吹某种方法论的人,因为我不相信其中任何一种方法比其他方法更有效。我所知道的是,没有方法论的组织肯定会失败,所以当没有方法的组织采用一种方法时,他们就会成功。沐鸣下载

TechRepublic的文章是对的。如果你的组织不解决上面提到的十个挑战,你的DevOps实施将会失败。但是,如果您的组织正在与本文所讨论的这十个挑战作斗争,那么无论您是否在实施DevOps,您的组织都注定要失败。

沐鸣注册网站架构云系统和DevOps部署的人工方面

AWS云架构副总裁Adrian Cockcroft认为,构建云系统的最大挑战之一在于构建事物的人方面。除了在亚马逊的工作,科克罗夫特还在架构Netflix的云战略方面发挥了关键作用。在Netflix崛起后,他经常在首席信息官圆桌会议上发言,大家总是问他这些超级明星工程师是从哪里来的。“好吧,我们都是从你那儿雇来的,”他会回答。沐鸣注册网站

多年来,科克罗夫特一直在思考是什么让Netflix如此吸引顶尖人才。其中一个因素是Netflix非常进步的开源项目,它让开发者可以自豪地与更大的开发者社区分享。这也有吸引招聘人员的危险,而招聘人员可能会把程序员挖走。沐鸣平台

薪酬和财务或声誉

为了解决这个问题,Netflix制定了一个非常积极的补偿计划。每年都会对程序员进行评级,并根据雇佣具有类似才能的人的成本进行补偿。这在许多关注百分比增长的企业中可能不会实现。科克罗夫特说:“我不知道还有哪家公司每年都这样做。”

另一个好的做法是通过组织一个“杰出工程师”或“研究员”圈子来确立重要人才的地位。一旦这个圈子足够大,成员们就可以提名其他人加入这个团体,这个团体就变成了某种精英俱乐部。进入这个团队的方法就是为其他杰出的工程师提供价值。随着时间的推移,这些杰出的工程师会作为一个团队相互了解,从而建立凝聚力和忠诚度。沐鸣登录

Amber项目:Java的未沐鸣测速登录地址来暴露

关注Var/Val,枚举和Lambda

Amber项目是去年1月首次引入的,当时Java语言架构师Brian Goetz提议创建一个项目,以探索和孵化更小的、面向生产力的Java语言特性。沐鸣测速登录地址

作为这个项目一部分的特性的主要前提是:它们已经被作为候选JEPs接受,也被称为JDK增强提案。在这个过程中,Oracle收集增强Java开发工具包和OpenJDK的建议。经过批准的建议将继续成为Java中的实际特性

Goetz指出,这个项目不是用来思考或讨论改进Java的新想法的地方,“互联网的其余部分仍然可用”。

3月16日,Goetz将Amber项目引入了Java社区,同时也引入了之前采纳的三个Java增强建议:

扩展类型推断到局部变量的初始化声明

-增强枚举(JEP 301) -特性和能力,将使枚举更好

  • Lambda剩余物(JEP 302) -提高Lambda的可用性沐鸣网址

为什么这三个项目会得到如此特别的关注?让我们找出答案。

满足项目的新功能

局部变量类型推断

大多数开发人员使用Java的一个主要问题是它太冗长。当阅读并试图理解其他开发人员在编写函数时的想法时,这可能是一件好事,但在实际编写这些函数时,这可能会变得乏味。

如果您想了解这个特性的更多信息,以及社区对它的看法,请参阅我们对新的Java本地变量类型推断语言特性的动手概览。

增强的枚举

这个特性的目标是增强Java语言中enum结构的表现力。正如提案中所述,Java枚举是一种功能强大且常用的构造。它们允许对常量进行分组,其中每个常量都是一个单例对象。当变量必须等于为其预定义的值之一时,它允许变量是一组预定义的常量。例如,每周的天数。

增强将允许枚举中的类型变量(泛型支持),这可以扩展枚举。它还将为枚举常量提供更精确的类型检查,以验证和强制枚举的约束。

支持泛型的枚举将允许我们指示具有关联类型的键集,并且我们将能够向单个项添加方法。这两个特性将协同工作,使enum常量能够携带特定于常量的类型信息以及特定于常量的状态和行为。增强枚举将允许我们用泛型类型定义枚举。可以显示此特性的一些值的一个例子是在表示数学常量时:

在这个示例中,我们可以添加对其他方法的支持,同时仍然享受每个方法的类型安全性。当underlyingObject不必是Object类型时,沐鸣开户向enum的构造函数传递不同类型的能力展示了该特性可以为表带来的优雅

增强枚举的另一个有用应用是减少在不同数据类型之间转换的样板代码。例如,jdbc类型转换为Java类型。它可以帮助增强代码自文档化的能力,并避免代码闻起来像“instanceOf”检查。

λ的剩饭剩菜

项目Lambda是在2014年随Java 8一起发布的,但总有改进的空间。这里的想法是通过增强方法上下文中函数表达式的消歧性来提高lambda表达式和方法引用的可用性。

该特性还关注于完成下划线字符的恢复,以指示未使用的lambda参数,并允许lambda参数在封闭范围中隐藏变量。

使用下划线作为未命名lambda参数符号的概念在其他语言中已经存在,我们的目标是使它也成为Java的一部分。使用非常简单,看起来是这样的:

沐鸣下载Apache Spark中的容错。

Apache Spark中的容错介绍

在开始学习Spark中的容错功能之前,沐鸣下载让我们先为初学者修改一下Apache Spark的概念。

现在让我们了解什么是故障以及Spark如何处理容错。

故障是指故障,因此容错能力就是要

操作并在故障发生后恢复损失。如果我们想

系统要有容错能力,就应该是冗余的,因为我们需要

冗余组件来获取丢失的数据。错误的数据是

由冗余数据恢复。

火花RDD容错

首先让我们看看如何在Spark中创建RDDs。

Spark在HDFS或S3等容错文件系统中对数据进行操作。

因此,所有由容错数据生成的RDDs都是容错的。沐鸣代理:

但是对于流/实时数据(数据通过

网络)。因此,对火花容错的关键需求就是这种类型

的数据。Spark的基本容错语义是:

从Apache Spark RDD开始

是一个不可变的数据集,每个星火RDD记得沿袭

对容错输入数据集使用的确定性操作

创建它。

如果由于工作节点故障导致RDD的任何分区丢失,

然后,该分区可以重新计算从原来的容错

使用沿袭操作的数据集。

假设所有的RDD转换都是确定的,那么最终转换的RDD中的数据总是相同的,而不考虑Spark集群中的故障。

为了实现对所有生成的RDDs的容错,实现了

方法中的工作节点中的多个Spark执行器之间复制数据

集群。这导致需要恢复两种类型的数据

失败时:1)数据接收并复制。2)数据已接收,但已缓冲以便复制。

接收和复制的数据:在这种情况下,将在其他节点上复制数据,因此当出现故障时可以检索数据。

已接收但已缓冲以便复制的数据:数据未被复制,因此恢复错误的唯一方法是再次从源检索它。

工作节点和驱动节点也会发生故障。

工作节点故障:在Spark集群上运行应用程序代码的节点

是火花工作人员节点。这些是从属节点。任何一个工人

运行executor的节点可能失败,从而导致内存丢失

任何接收器都运行在失败的节点上,那么它们的缓冲区数据将会

是输了。沐鸣平台注册登录

驱动节点失败:如果有一个失败

运行Spark流应用程序的驱动程序节点

SparkContent丢失,所有执行器及其内存中的数据丢失

丢失。

沐鸣测速登录地址这个12因素应用程序是为傻瓜开发的云本地应用

Yegor Bugayenko前几天写了一篇有趣的博客,标题为“SOLID是面向傻瓜的OOP”。好吧,如果SOLID是面向对象编程的假人,我想知道他是否同意我的断言,即12因素应用的咒语是假人等同于云本地开发?沐鸣测速登录地址

我喜欢Bugayenko的文章,尽管他似乎在评论中受到了不少抨击。但我完全同意他的前提。对我来说,告诉软件开发人员他们的应用程序应该遵循坚实的原则,就像告诉马拉松运动员最好的前进策略是循环地移动一条腿到另一条腿。当然,这句话是对的,但是从本质上来说不言自明的东西真的可以算作建议吗?

再次回顾SOLID原则

很快,坚实的原则如下:

·职责单一

·面向对象(O)

·使用多态性,或Liskov替换原则(L)

·利用接口(I)

·使用依赖倒置原则(D)对代码进行抽象

所以我将看到Bugayenko固体的五个原则的批评,让他一个类似的批评世界12-factor原生云应用。(顺便说一下,如果你不熟悉所有的最新的口头禅,肯•欧文斯的定义提供了一个很好的进行本文将敏捷,DevOps, 12-factor应用和原生云计算在一起)

重新访问12因应用程序

对于外行来说,以下是云本地计算这款12要素应用的12条原则:

  1. 代码库:一个代码库在修订控制中被跟踪,许多代码库被部署
  2. 依赖关系:显式地声明和隔离依赖关系

3.配置:在环境中存储配置

  1. 支持服务:将支持服务视为附加资源
  2. 构建、发布、运行:严格分离构建和运行阶段
  3. 进程:作为一个或多个无状态进程执行应用程序
  4. 端口绑定:通过端口绑定导出服务
  5. 并发性:通过流程模型向外扩展
  6. 一次性:快速启动和优雅关机,最大限度地增强健壮性
  7. 开发/产品等值:使开发、阶段和生产尽可能相似
  8. 日志:将日志视为事件流
  9. 管理进程:作为一次性进程运行管理/管理任务

不证自明的真理

严肃地说,我们真的需要告诉软件开发人员保持生产、开发和登台环境尽可能的相似吗?坦白地说,我不记得有哪个项目团队会说‘嘿,让我们让DEV和PROD完全不同吧’。比如,让我们在开发中使用MongoDB,在生产中使用DB2。”
打破了牢不可破的

老实说,有些原则我甚至不知道如何去违背。应用因素四表示支持服务应该被视为附加资源。我甚至不知道如何编写一个不将支持服务作为附加资源的云本地应用程序。这句话是不是太重复了,因为它是一个后端资源,而不是附加到你的云本地应用程序?

也许是因为我在过去的20年里一直在Spring和Java EE平台上进行开发,所以这些观点似乎是多余的。应用程序因素三指示本地云开发人员将配置细节存储在环境中,而不是作为一组常量或if-then-else语句,散布在整个代码库的各种不同类中。坦率地说,我看不到有经验的专业人士会添加这样的Java代码:在每个类中加入条件语句,根据当前承载代码的环境改变运行时行为。此外,将配置存储在应用程序之外并抽象出依赖关系一直是Spring和Java EE的基本原则。这正是资源引用和JNDI绑定存在的原因。

不成熟的想法

如果不是Spring或Java EE执行这些最佳实践,那么是应用服务器本身执行这些最佳实践。应用程序因素11指出,日志应该由执行环境捕获,并与云本地应用程序使用的所有其他日志流进行比较。老实说,我不记得WebSphere什么时候没有这样做。也许IBM可以吞并本地云计算行业中的所有小公司,创建一个新的、本地云应用服务器,并向业界展示如何进行日志记录?即使您只是在使用System,这种类型的功能也一直被正确地置于应用服务器运行时中。调用out,而不是像slf4j这样的日志框架。

这款名为12 factor的应用确实提供了一些值得思考的东西,大部分智力上可以吃的东西都来自于一种坚持,即使用一个过程(而不是线程)是衡量规模的最佳方式。尽管我认为这只是一个语义上的论证,而不是基于实践的论证。虽然传统的Java应用程序服务器确实运行一个具有多个线程的进程,但Java微服务往往是单处理的,甚至在微服务中,也会有多个利用线程的功能,因此它并不是一种非此即的事情。如果有的话,作为流程执行应用程序和使用流程模型向外扩展的因素6和8,确实可以归结为这样一个断言:大块是不好的,而将大块分解成更小的块是好的。我想我们最近已经听够了这个咒语了。是的,我们知道了。杏耀注册平台官网

Facebook分享和网络迷因

在我看来,这款12要素应用程序的每一条格言,就像你挂在全国各地办公室里那些恼人而鼓舞人心的海报上的一样。我几乎能想象到一张意大利跑车的海报,上面写着“一次性”,下面写着“快速启动和优雅关机,最大化稳健性”。我们生活在这样一个时代,为了被消费,每条信息都必须以模因的形式传播,或者以Facebook帖子或140个字符的推文的形式传播。也许这个12要素应用的咒语是为新开发人员、社交媒体的千禧一代服务的?

12因子应用和云原生模因

这款12元素的应用已经成为了网络流行语

告诉我少吃多运动来减肥是很没用的建议。告诉我按时缴税,避免利息和罚款也是没用的建议。我的意思是,这些陈述是正确的,但没有什么是我不知道的,这使得陈述这些重复的陈述是浪费时间。你可以把这些陈述框定为建议,但如果它们没有提供新的、没有增加价值、没有特别可执行的东西,那就真的不是建议。我不禁觉得关于创建12元素应用程序的所有讨论都属于同一类别。我不知道耶戈尔·布加连科是否会同意我的观点?沐鸣平台