Skip to main content

A Bite of ChinaⅡ

· One min read
Lex
Front End Engineer @ Baoxiaohe

《舌尖上的中国 第二季》

无论多么惊心动魄的历史进程,落在食物上,都是不落声色的简单。

历史,对于旁观者,是一段故事;对于亲历者,却是切身的喜悦和感伤。

How to read faster

· One min read
Lex
Front End Engineer @ Baoxiaohe

意群拆分

Stop sub-vocalisation#

如果能避免默读,我相信阅读速度会提升一大截。所谓阅读理解,我只要知道文章阐述了什么主题就好,完全不需要花时间在这个单词怎么发音,那句话怎么念上。

想要一下子就完全避免阅读过程中默念是很难的,我们可以用其他声音代替,比如en,weng这样的拟声词。一开始这样 multithreading 可能效果不是很好,whatever 坚持下去。

Eliminate Distractions#

快速阅读需要无比专注,不然通篇看完你也可能什么都没记住。所以关掉那些没有意义的 noise,找一个安静的地方然后 Keep Practicing ,对于有阅读障碍的人来说,唯一的办法就是多练习。

Groups of Words#

讲视线对焦到一个个意群而不是一个个单词。

阅读是眼睛快速移动的过程,但不是光滑地在文字上扫描,而是从一个凝视点跳到另一个凝视点。当眼睛在移动和停顿交替的过程中,只有在停顿时才能接受信息,这些停顿占据了阅读的大部分时间。

解决了默读的问题,我们已经能确保停顿的时间都花在获取字面信息上,所以接下来要提高的就是每次停顿获取的信息量。如果每次凝视只能看到一个单词的话,你获取信息的效率就太低了,而你应当看到的是一个短语、词组、一部分信息,也就是我们说的意群。意群的快速划分需要大量阅读的积累。

我们以这段文字为例:

  • The way to read faster is to take in groups of words at a time.

在你眼中的这段文字,应当分为四个意群:

The way to read faster,is to take in, groups of words, at a time

在阅读的过程中要不断尝试扩大每次凝视的宽度,从而在单位时间内获取更多的信息。

Active Reading#

类似带着问题去阅读,明确阅读目标并主动探索文章内容,合理思考文章走向,在阅读过程中能让自己的思考得到及时的反馈。

Grammar#

对于学术文档里的长难句,最核心的就是————跳修饰,抓主干。所以在阅读英文长难句的时候,你可以选择读两遍,第一遍透过主干快速掌握句意,第二遍再根据需要把修饰部分当做补充信息来理解。

语法部分就需要一定量的积累和学习了,可以参考考研英语长难句学习。

参考#

公子若. 如何提高英文阅读速度

阙苗烨 Hazel. 如何提高英文阅读速度

文字的发展

· One min read
Lex
Front End Engineer @ Baoxiaohe

Vue.js的名称来自法语,英语里是没有这个词的。随着 Vue框架的兴起, 才有了Vue这个网络用语。

类似中文里的,也是网络造词后被加入词典,汉字文明又向着四千年迈进一小步。

同样,Vite.js中的 Vite 也是法语,所以发音并不是英语中的[vi:t,vit],而是[vit]

前端模块化的发展

· 2 min read
Lex
Front End Engineer @ Baoxiaohe

这不就是最原始的 Web 引入 JavaScript 代码吗,只不过是以不同文件保存不同的功能代码和相关状态数据,这也能叫模块化。

早期的模块化

Stage1 文件划分方式#

问题也很多

  • 模块直接在全局工作,大量模块成员污染全局作用域;
  • 没有私有空间,所有模块内的成员都可以在模块外部被访问或者修改;
  • 一旦模块增多,容易产生命名冲突;
  • 无法管理模块与模块之间的依赖关系;
  • 在维护的过程中也很难分辨每个成员所属的模块。

Stage2 命名空间方式#

后来,我们约定每个模块只暴露一个全局对象,所有模块成员都挂载到这个全局对象中,具体做法是在第一阶段的基础上,通过将每个模块“包裹”为一个全局对象的形式实现,这种方式就好像是为模块内的成员添加了“命名空间”,所以我们又称之为命名空间方式。这种命名空间的方式只是解决了命名冲突的问题,但是其它问题依旧存在。

Stage3 IIFE#

使用立即执行函数表达式(IIFE,Immediately-Invoked Function Expression)为模块提供私有空间。具体做法是将每个模块成员都放在一个立即执行函数所形成的私有作用域中,对于需要暴露给外部的成员,通过挂到全局对象上的方式实现。

这种方式带来了私有成员的概念,私有成员只能在模块成员内通过闭包的形式访问,这就解决了前面所提到的全局作用域污染和命名冲突的问题。

Stage4 IIFE 依赖参数#

在 IIFE 的基础之上,我们还可以利用 IIFE 参数作为依赖声明使用,这使得每一个模块之间的依赖关系变得更加明显。

(function ($) {  var name = "module-a";  function method1() {    console.log(name + "#method1");    $("body").animate({ margin: "200px" });  }  window.moduleA = {    method1: method1,  };})(jQuery); // 通过参数明显表明这个模块的依赖

不可避免的问题#

以上只是模块化的约定,并不是行业规范,没有统一的实现标准所以不同开发者的实现会有细微的差别。

另外最明显的问题就是:模块的加载。在这几种方式中虽然都解决了模块代码的组织问题,但模块加载的问题却被忽略了,我们都是通过 script 标签的方式直接在页面中引入的这些模块,这意味着模块的加载并不受代码的控制,时间久了维护起来会十分麻烦。

更为理想的方式应该是在页面中引入一个 JS 入口文件,其余用到的模块可以通过代码控制,按需加载进来。

模块化规范的出现

CommonJS是 Node.js 中遵循的模块规范,该规范约定,一个文件就是一个模块,每个模块都有单独的作用域,通过 module.exports 导出成员,再通过 require 函数载入模块。但是如果我们想要在浏览器端直接使用这个规范,那就会出现一些新的问题。

CommonJS 约定的是以同步的方式加载模块,Node.js 执行机制是在启动时加载模块,执行过程中只是使用模块,所以这种方式不会有问题。但是如果要在浏览器端使用同步的加载模式,就会引起大量的同步模式请求,导致应用运行效率低下。所以在早期制定前端模块化标准时,并没有直接选择 CommonJS 规范,而是专门为浏览器端重新设计了一个规范,叫做 AMD ( Asynchronous Module Definition) 规范,即异步模块定义规范。同期还推出了一个非常出名的库,叫做 Require.js,它除了实现了 AMD 模块化规范,本身也是一个非常强大的模块加载器。

Require.js 还提供了一个 require() 函数用于自动加载模块,用法与 define() 函数类似,区别在于 require() 只能用来载入模块,而 define() 还可以定义模块。当 Require.js 需要加载一个模块时,内部就会自动创建 script 标签去请求并执行相应模块的代码。

ES Modules#

CommonJS 属于内置模块系统,所以在 Node.js 环境中使用时不存在环境支持问题,只需要直接遵循标准使用 require 和 module 即可。

但是对于 ES Modules 规范来说,情况会相对复杂一些。我们知道 ES Modules 是 ECMAScript 2015(ES6)中才定义的模块系统,也就是说它是近几年才制定的标准,所以肯定会存在环境兼容的问题。在这个标准刚推出的时候,几乎所有主流的浏览器都不支持。但是随着 Webpack 等一系列打包工具的流行,这一规范才开始逐渐被普及。

经过 5 年的迭代, ES Modules 已发展成为现今最主流的前端模块化标准。相比于 AMD 这种社区提出的开发规范,ES Modules 是在语言层面实现的模块化,因此它的标准更为完善也更为合理。而且目前绝大多数浏览器都已经开始能够原生支持 ES Modules 这个特性了,所以说在未来几年,它还会有更好的发展,短期内应该不会有新的轮子出现了。

综上所述,如何在不同的环境中去更好的使用 ES Modules 显得尤为重要。

模块打包工具的出现

模块化可以帮助我们更好地解决复杂应用开发过程中的代码组织问题,但是随着模块化思想的引入,我们的前端应用又会产生了一些新的问题,比如:

  • 首先,我们所使用的 ES Modules 模块系统本身就存在环境兼容问题。尽管现如今主流浏览器的最新版本都支持这一特性,但是目前还无法保证用户的浏览器使用情况。所以我们还需要解决兼容问题。
  • 其次,模块化的方式划分出来的模块文件过多,而前端应用又运行在浏览器中,每一个文件都需要单独从服务器请求回来。零散的模块文件必然会导致浏览器的频繁发送网络请求,影响应用的工作效率。
  • 最后,谈一下在实现 JS 模块化的基础上的发散。随着应用日益复杂,在前端应用开发过程中不仅仅只有 JavaScript 代码需要模块化,HTML 和 CSS 这些资源文件也会面临需要被模块化的问题。而且从宏观角度来看,这些文件也都应该看作前端应用中的一个模块,只不过这些模块的种类和用途跟 JavaScript 不同。

第一,它需要具备编译代码的能力,也就是将我们开发阶段编写的那些包含新特性的代码转换为能够兼容大多数环境的代码,解决我们所面临的环境兼容问题。第二,能够将散落的模块再打包到一起,这样就解决了浏览器频繁请求模块文件的问题。这里需要注意,只是在开发阶段才需要模块化的文件划分,因为它能够帮我们更好地组织代码,到了实际运行阶段,这种划分就没有必要了。第三,它需要支持不同种类的前端模块类型,也就是说可以将开发过程中涉及的样式、图片、字体等所有资源文件都作为模块使用,这样我们就拥有了一个统一的模块化方案,所有资源文件的加载都可以通过代码控制,与业务代码统一维护,更为合理。

Webpack 发展到今天,它的功能已经非常强大了,但依然改变不了它是一个模块化解决方案的初衷。你可以看到, Webpack 官方的 Slogan 仍然是:A bundler for javascript and friends(一个 JavaScript 和周边的打包工具)。 从另外一个角度来看,Webpack 从一个“打包工具”,发展成现在开发者眼中对整个前端项目的“构建系统”,表面上似乎只是称呼发生了变化,但是这背后却透露出来一个信号:模块化思想是非常伟大的,伟大到可以帮你“统治”前端整个项目。这也足以见得模块化思想背后还有很多值得我们思考的内容。

Webpack 以模块化思想为核心,帮助开发者更好的管理整个前端工程。

Webpack 运行机制与核心工作原理#

  • 通过 Loader 处理特殊类型资源的加载,例如加载样式、图片;
  • 通过 Plugin 实现各种自动化的构建任务,例如自动压缩、自动发布。

整个打包过程中,Loader 机制起了很重要的作用,因为如果没有 Loader 的话,Webpack 就无法实现各种各样类型的资源文件加载,那 Webpack 也就只能算是一个用来合并 JS 模块代码的工具了。至于自定义插件机制,它并不会影响 Webpack 的核心工作过程,只是 Webpack 为了提供一个强大的扩展能力,它为整个工作过程的每个环节都预制了一个hook,也就是说我们可以通过插件往 Webpack 工作过程的任意环节植入一些自定义的任务,从而扩展 Webpack 打包功能以外的能力。

具体来看打包的过程,Webpack 启动后,会根据我们的配置,找到项目中的某个指定文件(一般这个文件都会是一个 JS 文件)作为入口。然后顺着入口文件中的代码,根据代码中出现的 import(ES Modules)或者是 require(CommonJS)之类的语句,解析推断出来这个文件所依赖的资源模块,然后再分别去解析每个资源模块的依赖,周而复始,最后形成整个项目中所有用到的文件之间的依赖关系树,有了这个依赖关系树过后, Webpack 会遍历(递归)这个依赖树,找到每个节点对应的资源文件,然后根据配置选项中的 Loader 配置,交给对应的 Loader 去加载这个模块,最后将加载的结果放入 bundle.js(打包结果)中,从而实现整个项目的打包。对于依赖模块中无法通过 JavaScript 代码表示的资源模块,例如图片或字体文件,一般的 Loader 会将它们单独作为资源文件拷贝到输出目录中,然后将这个资源文件所对应的访问路径作为这个模块的导出成员暴露给外部。

关键环节#

这里我们先提炼出 Webpack 核心工作过程中的关键环节,明确“查阅”源码的思路:

  1. Webpack CLI 启动打包流程;
  2. 载入 Webpack 核心模块,创建 Compiler 对象;
  3. 使用 Compiler 对象开始编译整个项目;
  4. 从入口文件开始,解析模块依赖,形成依赖关系树;
  5. 递归依赖树,将每个模块交给对应的 Loader 处理;
  6. 合并 Loader 处理完的结果,将打包结果输出到 dist 目录。

How to understand the Reactivity System in Vue

· 4 min read
Lex
Front End Engineer @ Baoxiaohe

As we all know,MVVM is an acronym of Model,View and ViewModel.

What's MVVM#

早先前端页面只是用来展示文本,与用户的交互很少。对于一些需要操作 DOM 的的需求使用 JQuery 这个解决方案就足够了。但随着需求的增多和复杂化,频繁操作 DOM 显得很不优雅。 MVVM MVVM 使数据和视图分开,Model 显示数据,View 显示 DOM 视图。View Model 负责监听数据的变化并将其渲染到 DOM,同时 DOM 的变化也会映射到 Model 层。

Reactivity System#

Vue realize reactive by data binding.That means you can only mudify data,than Vue will update views without handle DOM.Actually Vue will update node by virtual DOM,it faster than actual DOM.Different from React,Vue is by Object.defineProperty API and Observer design mode.

One of Vue’s most distinct features is the unobtrusive reactivity system. Models are proxied JavaScript objects. When you modify them, the view updates. It makes state management simple and intuitive, but it’s also important to understand how it works to avoid some common gotchas.

响应式原理

When you pass a normal JavaScript Object into a Vue instance as a data option, the Vue will walk through all the property of the Object and use Object.defineProperty to convert them all to getter/setter.Object.defineProperty is a non-shim feature in ES5, which is why the Vue doesn't support IE8 and lower browsers.The getter/setter is not visible to the user, but inside they make Vue could tracking dependencies, when the property is accessed and modified notice changes. To note here is that the different browsers in the console print data object format is different with getter/setter, so suggest install vue-devtools to obtain more user-friendly interface to check the data.

Each component instance map to a watcher instance, it will contact in the process of the component rendering the passed data's property is recorded as a dependency. Then when the setter of the dependency fires, it notifies Watcher, causing its associated component to rerender.

简单的说就是 Vue 会把data对象中所有propertyreactive 化,也就是加上 setter 和 getter,而这对用户是不可见的。

Object.defineProperty#

What is Object.defineProperty API,it play what role?For example,we define a variate b from obj like that:

let aValue;let obj = {};Object.defineProperty(obj, "b", {  get() {    console.log("监听正在获取a");    return aValue;  },  set(newValue) {    console.log("监听正在设置a");    aValue = newValue;  },  enumerable: true,  configurable: true,});obj.b;obj.b = 40;

We would get result:

监听正在获取 a
监听正在设置 a

So we know,it trigger getter when we visit variate from an Object,and trigger setter when we set the variate.Then,we can realize a sample reactive demo like that:

    <input type="text" id="txt" /><br />    <span id="sp"></span>
    <script>      let obj = {},        txt = document.getElementById("txt"),        sp = document.getElementById("sp");
      Object.defineProperty(obj, "msg", {        get() {          return txt.value;        },        set(newValue) {          txt.value = newValue;          sp.innerText = newValue;        },      });
      txt.addEventListener("keyup", (event) => {        obj.msg = event.target.value;      });    </script>

In effect,that's the principle for change detection in Vue.js.我们可以封装一下代码简化一下传参。

function defineReactive(data, key, val) {  Object.defineProperty(data, key, {    enumerable: true,    configurable: true,    get() {      return val;    },    set(newValue) {      if (val === newValue) {        return;      }      val = newValue;    },  });}

变化侦测起到了追踪变化的作用,但是更重要的是要收集依赖,我们之所以要追踪变化,就是为了当数据的属性发生变化时,可以通知那些使用到该数据的地方不是吗?所以就需要先收集依赖,等到数据发生了变化,再把之前收集到的依赖循环触发一遍就好了。显然,这就是观察者模式需要处理的问题了。

Observe design mode#

Ok,we know what's Object.defineProperty now,how about Observer design mode?
这里举个很简单的栗子:
我们喜欢一个明星(such as Evan You)就会去关注他的动态,例如去微博上点关注。此时微博就充当了观察者,它接收 Evan 发送的微博,然后将它们发送给订阅了 Evan 微博的粉丝。当黑粉取消订阅后,微博当然也就不再发送 Evan 的微博动态给黑粉们了。

Observer

So,there has three functions:the first is regist() 用来订阅.The second is notify() 用来广播动态.The third is remove() 用来取消订阅。Now we can realize a simple Observer model:

class Observer {  constructor() {    // we need container collect regist imformation    this.dep = [];  }
  regist(fn) {    this.dep.push(fn);  }
  notify() {    this.dep.forEach((item) => item());  }}

Vue 的响应式原理#

  1. init 阶段:Vue 的 data 的property都会被reactive化,也就是加上setter/getter函数。
function defineReactive(obj: Object, key: string, ...) {    const dep = new Dep()
    Object.defineProperty(obj, key, {      enumerable: true,      configurable: true,      get: function reactiveGetter () {        ....        dep.depend()        return value        ....      },      set: function reactiveSetter (newVal) {        ...        val = newVal        dep.notify()        ...      }    })  }
  class Dep {      static target: ?Watcher;      subs: Array<Watcher>;
      depend () {        if (Dep.target) {          Dep.target.addDep(this)        }      }
      notify () {        const subs = this.subs.slice()        for (let i = 0, l = subs.length; i < l; i++) {          subs[i].update()        }      }

源码将收集依赖的容器dep[]封装到 Dep 类中,每个 data 的property都有一个 dep 对象。当 getter 调用的时候去 dep 里执行depend()收集依赖,当 setter 调用时去 dep 里执行notify()触发依赖。

  1. mount 阶段
  2. update 阶段

参考 知乎还是掘金上的文章,腾讯女大佬。后面东西之后再补充吧...

博客的意义

· One min read
Lex
Front End Engineer @ Baoxiaohe

Why begin write#

现在人很有专研精神,凡事都求个为什么,为什么,为什么呢?这样做有什么意义? 给自己看,单纯的做个记录。如果有被其他读者看到,如果不是有缘,就是我觉你应该参与进我的生活。 读了这么些年书,总觉得应该写出点什么文字出来以慰藉自己无用的灵魂。 以输出的方式倒逼输入,能促使我开始学习。 如此这般,这般如此,意义就出来了。

Why here#

分享 idea 的社交平台很多,搭建个人博客对我来说也不是很难。不用辛苦地为社交平台贡献流量(好像说反了 🐱‍🐉),意味着多年为地主辛勤耕作的农民终于有了自己的土地,

只是这农民,他是个码农 🧗‍♂️。

Welcome

· One min read
Lex
Recent Graduate

It's a big day for me.I finded my first job.Whatever,learn and grow on the job.

最好的告别

· 2 min read
波波
junior student @ JXAU

关于衰老与死亡,你必须知道的常识

阿图·葛文德 王一方主编

44 个想法

总序 了不起的葛文德#

恋生恶死是人之常态,但死亡面前人人平等,无论你是国王,还是车夫,是大亨,还是乞丐,地位与金钱都无法改变个体生命必死的事实。人生的最后一道考题就是如何面对死神的召唤,恐惧、沮丧、忧伤是人之常情,再坚强、豁达的人在死神面前也无法高傲、从容起来。现世的花红柳绿、死亡过程的挣扎抗拒和对于来世的困惑迷茫都是死亡降临时不可避免的纠结。但是无论怎样纠结,我们还是需要迈过那一道门槛,去远方遨游。如何安顿这颗不安的灵魂,是现代安宁缓和医疗的首要课题,也是每个凡人需要借助灵魂修炼才能坦然面对的生命节目。

自序 一介凡夫 医生也许都想错了#

应该如何优雅地跨越生命的终点?对此,大多数人缺少清晰的观念,而只是把命运交由医学、技术和陌生人来掌控。

好在我们的社会已经意识到这是一个待解的问题,我们正在为生命的末期关怀开辟安宁缓和医疗(临终关怀)的新路径。到那一天,生的愉悦与死的坦然都将成为生命圆满的标志。

03 依赖 我们为老做好准备了吗#

高龄老人告诉我,他们最害怕的并不是死亡,而是那之前的种种状况——丧失听力、记忆力,失去最好的朋友和固有的生活方式。正如菲利克斯对我说的:“老年是一系列连续不断的丧失。”

衰老是一系列的丧失#

在生命的最后几个星期,她安宁地住在家里,享受着他们的漫长爱情的温暖,而不是作为一个心智迷失、思维混乱的病人住在疗养区。

应运而生的疗养院#

。他告诉一位朋友:“如果我明天死去,我也已经度过了愉快的一生。我能做的事都做了,想做的事都做了。”

老了但对生活的要求不能仅仅是安全#

谁能想到在某种情境下,吃个饼干就能构成反抗呢?

在我们衰老脆弱、不再有能力保护自己的时候,如何使生活存在价值。

什么时候可以考虑去老人院看一看#

一旦衰老导致衰弱,似乎就没人可以活得快乐。

有没有一个真正像家的“老年之家”#

1943 年,心理学家亚伯拉罕·马斯洛(Abraham Maslow)发表了他影响巨大的论文《人类动机论》(A Theory of Human Motivation),

当“生命的脆弱性凸显出来”时,人们的日常生活目标和动机会彻底改变。至关紧要的是观念,而不是年龄。

用两条狗、4 只猫、100 只鸟发起的革命#

“文化具有极大的惰性,”他说,“所以它是文化。它之所以能发挥作用,是因为它持久。文化会把创新扼杀在摇篮中。”

我相信死亡率的差异可以追踪到人对于活着的理由的根本需求。

针对厌倦感,生物会体现出自发性;针对孤独感,生物能提供陪伴;针对无助感,生物会提供照顾其他生命的机会。

修复健康,也需滋养心灵#

随着年龄增长,我们都学会从简单的愉悦中寻求慰藉——友情、日常的例行公事、好食物的味道,以及阳光照在脸上的那种温暖。我们对于实现和积累的奖赏兴趣变小了,对于仅仅活着的奖赏兴趣加大了。然而,一方面我们感觉没那么雄心勃勃了,同时,我们对于我们的遗产又更加关心了。我们深深感到一种需要,必须确认外在于我们,使我们觉得活着更有意义、更有价值的目标。

生活中最好的事,就是能自己上厕所#

“我在那儿好开心啊。我是在生活,我过的是人应该过的生活:我有朋友,能玩游戏。有个人会开车,我们说走就走。我是在生活。”

战胜老年生活的无聊与无助#

对疾病和老年的恐惧不仅仅是被迫忍受对种种丧失的恐惧,同样也是对孤独的恐惧。当人意识到生命的有限,他们就不再要求太多。他们不再寻求更多的财富,不再寻求更多的权力。他们只要求,在可能的情况下,被允许保留塑造自己在这个世界的生命故事的权利——根据自己的优先顺序作出选择,维持与他人的联系。

100 种治疗方法不一定能有一种有用#

当我活到头的时候,我希望能平静地面对生命的终点,并且是以我自己选择的方式。

临终讨论专家的话术#

接受个人的必死性、清楚了解医学的局限性和可能性,这是一个过程,而不是一种顿悟。

,“那一刻,我的直觉会是让他走,因为情况太糟糕了。但是,之后我会痛打我自己,会不停质疑自己是不是让他走得太早。

他说,那最后的一个月,家人只是一心一意地待在一起,结果这是他们在一起度过的最有意义的时光。

07 艰难的谈话 为迎接生命的终点谋求共识#

要在人的必死性方面谋求共识,并以生命尊严和保持有意义生活作为生存追求,医患双方都面临着学习的任务,

选择可以信任的医生#

那一刻,我们仿佛一下子进入了另一个生死攸关的世界,有关我父亲的生活及一切期待瞬间变得面目全非。我们全家开始面对身边人终有一死的事实。无论父母还是子女,我们都要经历一场考验。父亲的治疗之路如何走,是认同生死、顺应生死,还是全力抵抗、永不言弃?作为一个医生,走技术救助的惯性之路轻而易举,但要作出新的选择,却有所不同。如同一次新的竞赛,大家都没有做好准备,但发令枪已经响起,生死观的测试开始了。

理解个人生命的有限性#

直到现在,我才认识到,理解个人生命的有限性是一份怎样的礼物。

这就是所谓拥有自主性的意思——你不能控制生命的情形,但是,做自己生命的作者意味着要把握住自己想怎么应对。

少做一点也是一种帮助#

然而,选择并未停止。生活就是选择,而选择了无尽头。刚做完一个选择,下一个选择又摆在了面前。

在压力之下,他同意了。但是,结果证明这些预测愚不可及。这些专家不像本泽尔,他们没准备承认治疗带来的不确定性远远大于带来好处的可能性。他们也没准备花点儿时间去了解我父亲,了解放疗对他意味着什么。

她又加了一句:“这个夏天你可望回到网球场。”我难以相信她会说出这样的话。他还会回到网球场,这样的想法太疯狂了——根本一点儿希望都不存在。看到她用这个话忽悠我父亲,我简直要气疯了。我看到他想象自己重回网球场时脸上的表情。但是,此时,事实再一次证明他作为医生的明显好处。

谈话一直没有涉及他关心的问题——找到一条让他最有机会维持他觉得有价值的生活的途径。

她的这个回答既让我们难以接受,又出乎意料。“真没想到。”我父亲小声说。我想起了萨拉·莫诺波利的肿瘤医生保罗·马尔库克斯跟我说起他的病人:“我在想,有没有办法抢下一年或者两年?……而他们想的是 10 年、20 年。”我们也想的是 10 年、20 年。

临床医生唯一害怕犯的错误就是做得太少。大多数医生不理解在另一个方向上也可以犯同样可怕的错误——做得太多对一个生命具有同样的毁灭性。

选择比风险计算更复杂#

于是我退回来,问她我问过我父亲的问题:她最大的恐惧和关心有哪些?她最重要的目标有哪些?她愿意做哪些交换、不愿意做哪些交换?

所以,她的正确做法是什么?为什么选择这么痛苦?我意识到,选择比风险计算复杂多了。在消除恶心、恢复吃饭能力的机会与疼痛、感染和必须往袋子里排便的可能之间,如何进行权衡?

多个背景下的研究都证实了峰终定律以及我们对疼痛长度的忽视。研究还说明,这个现象也同样适用于人们对愉快经验的评价。每个人都了解观看体育比赛的经验:一支球队在整个比赛中都表现得很出色,但是在结束的时候出了意外状况,我们会觉得糟糕的结尾毁了整体感受。然而,这个判断在根源处有一个矛盾:体验的自我获得了几个小时的愉快,而只有一小会儿的不愉快,但是记忆的自我则看不到任何的愉快。

两周后,道格拉斯的女儿苏珊给我写了一封信。“妈妈于周五早晨去世了。她在安静的睡眠状态中停止了呼吸,走得非常平静。当时我爸爸一个人陪在她身边,我们其他人都在客厅。这个结局是如此完美,正如我父母之间的关系。”

善终不是好死而是好好活到终点#

我从来不敢说结局可以控制,因为没有人真的能够控制。说到底,物理学、生物学和意外事故对我们的生活为所欲为。但是重点在于,我们也并不是完全无能为力的。所谓勇气,就是同时认识到这两个事实

我们在对待病人和老人方面最残酷的失败,是没有认识到,除了安全和长寿,他们还有优先考虑事项;建构个人故事的机会是维持人生意义的根本;通过改变每个人生命最后阶段的可能性这一方式,我们有机会重塑我们的养老机构、我们的文化和我们的对话。

技术化的社会已经忘记了学者所谓的“垂死角色”(dying role),以及生命接近终点时,它对于人们的重要意义。人们希望分享记忆、传承智慧和纪念品、解决关系问题、确立遗产、与上帝讲和、确定留下的人能好好活着。他们希望按照自己的主张结束自己的故事。观察者认为这个角色无论对于逝者,还是对于活着的人,都是生命最重要的内容。如果是这样,那么,我们出于愚钝和忽视而剥夺人们的这个角色,就应该永远感到羞愧。一而再地,我们医学领域中的人在人们生命的终点给他们造成深刻的伤害,并对造成的伤害毫无觉察。

和父亲最后的对话#

一个人的生命走到尽头的时候,也就是做决定的责任转移到另一个人身上的时候。

这个过程中,他一直紧闭着双眼。谁会想到自己会有这一天呢?终于,我把导尿管插了进去,尿一下子奔涌而出。那一瞬间的舒畅感无疑是强烈的。

尾声 三杯恒河水 思考死亡是为了活得更好#

对于医学工作者的任务究竟是什么,我们一直都搞错了。我们认为我们的工作是保证健康和生存,但是其实应该有更远大的目标——我们的工作是助人幸福。

。无论什么时候身患重病或者受伤,身体或者心智因此垮掉,最重要的问题都是同样的:你怎么理解当前情况及其潜在后果?你有哪些恐惧,哪些希望?你愿意做哪些交易,不愿意做哪些妥协?最有助于实现这一想法的行动方案是什么?

恒河对于世界上最大的宗教之一可能是神圣的,但是对于身为医生的我来说,它更突出的地方在于它是世界上污染最严重的河流之一,而这部分是那些被扔进河里、未充分火化的尸体所致

漂浮在这条水流汹涌的历史长河中,我情不自禁地感到无数代人的手穿越时间相握在一起。通过把我们带到这里,我父亲帮助我们理解,他是有着几千年历史渊源的故事的一部分——我们也是。

译者后记#

就人与人之间的情谊而言,美国人跟中国人那么相似,并不是传说中的人情冷漠。

· One min read
zhang13pro
junior of Jiangxi Agricultural University

收获后也是金黄色的

我爱这片土地

它有着最纯粹的美和“土”

城里人可以用土气去贬低乡下人

但是土是他们的命根

电影里出国的人随身带着家乡的土,用来治愈水土不服

足以见得土影响着的不仅仅是靠它生存的农民

更给中华民族刻下了深深的烙印