像写作一样去写代码,如何把异步的形式改写成同步的形式

写代码的时候,碰到一大堆的缩进、花括号是不是特别头疼?为什么会有这么多的标点符号,还有各种技术概念?能不能像写作一样,自由得书写?从形式上,代码比文章多的是格式,格式代表了对应的技术原理。文本分享一则关于「 同步 、异步、阻塞、非阻塞 」的技术概念,结合Javascript中的图片加载,介绍如何把异步的形式改写成同步的形式,更加优雅的书写我们的代码。

def CodeFun( ):

先来看这么一个故事:

领导M需要准备一份年终总结的PPT,

他把这件事安排给了下属L

故事1

领导M非常不放心L,

于是决定在L边上陪着他把PPT做完

技术原理::「 同步阻塞 」

旁白::这领导太低效了,自己动手不行吗?

故事2

M安排L做PPT后,

跑去会议室开会,

并时不时到下属L的工位前看看PPT做完没

技术原理::「 同步非阻塞 」

旁白::这是大部分领导的做法(显得自己很忙)

故事3

M在交代PPT任务时,

特定嘱咐L,

做完PPT要主动来找他。

但是M还是不放心,

决定等在L边上,

陪着他做PPT

技术原理::「 异步阻塞 」

旁白::有这样的下属,也是够操心的。

故事4

M在交代PPT任务时,

特定嘱咐L,

做完PPT要主动来找他。

此时,

M决定全权交给L负责,

自己继续在会议室开会

技术原理::「 异步非阻塞 」

旁白::下属L发挥自己的主动性,把PPT完美完成,领导M也完成了会议。

所谓同步异步,只是对于L而言:

L做完PPT后沉默不语,叫 「 同步 」;

L做完PPT主动汇报,叫「 异步 」。

「 同步 」 的情况下,M得自己主动去询问做完PPT没。

「 异步 」 的情况下,M可以忙自己的事,L做完PPT会主动汇报。

所谓阻塞非阻塞,仅仅对于M而言:

「 阻塞 」的情况下, M陪着L做PPT。

「 非阻塞 」的情况下,M去会议室开会。

显然,「 异步+非阻塞 」是最高效的。

这就是同步、异步、阻塞、非阻塞的概念的通俗理解。回到代码写作上,我们实际写代码的时候,会比较习惯一种「 线性思维 」的方式,这种方式有点类似于做数学证明题的过程:

因为等边△ABC

所以∠A=∠B=60度

又PE⊥AC

所以∠AEP是直角

所以∠APE=30度

在△PBQ中

∠B=60度,∠Q=28度

所以∠QPB=92度

所以∠EPD=180-92-30=58度

一行行的书写方式,逻辑性非常强,简单明了的因果关系 ,这是一种典型的线性思维。下面举一个Javascript的例子。初学JS的同学,为了把图片绘制到canvas上,一般会这么写:

var img=.....

....

ctx.drawImage(img,0,0);

我们初学的时候,习惯一行行的书写方式,把图片数据存储在一个变量img里,然后再调用绘图命令使用img。

我们可以在浏览器中打开「 开发者工具 」,在console面板中进行实验:

var img=new Image();

img.src="https://images.unsplash.com/photo-1543363951-ec6198f35a38?auto=format&fit=crop&w=100&q=30";

var canvas=document.createElement("canvas");

var ctx=canvas.getContext("2d");

ctx.drawImage(img,0,0);

document.body.innerHTML='';

document.body.appendChild(canvas);

运行下,如果按照以上的写法,经常会出现图片绘制不出来的情况,因为图片是「 异步 」加载的。这个时候,我们需要把代码改写下:

var img=new Image();

img.src="https://images.unsplash.com/photo-1543363951-ec6198f35a38?auto=format&fit=crop&w=100&q=30";

img.onload=function(){

var canvas=document.createElement("canvas");

var ctx=canvas.getContext("2d");

ctx.drawImage(img,0,0);

document.body.innerHTML='';

document.body.appendChild(canvas);

};

代码开始有了缩进,我们需要了解「 作用域 」的概念,我们继续把图片加载写成一个函数:

function loadImg(_url,_callback){

var img=new Image();

img.src=_url;

img.onload=function(){

_callback(img);

};

};

加载一张图片:

loadImg("http://xxxx",function(img){

...

});

如果是多张图片加载呢?

loadImg("http://xx1",function(img){

loadImg("http://xx2",function(img){

loadImg("http://xx3",function(img){

loadImg("http://xx4",function(img){

...

});

});

});

});

一层层的嵌套,写起来,看起来都非常难受😣,为了解决这个问题,Promise出现了,loadImg可以写出then这种方式:

loadImg("http://xxx")

.then(function(img){

....

});

多张图片的加载,变成了这样:

loadImg("http://xxx1")

.then(function(img){

....

});

loadImg("http://xxx2")

.then(function(img){

....

});

loadImg("http://xxx3")

.then(function(img){

....

});

是不是开始有点一行行在书写代码的感觉?但是还是有一个缩进在碍事。以上例子真实可运行的代码可以参考如下:

function loadImg(_url){

var img=new Image();

img.src=_url;

return new Promise(function(resolve, reject){

img.onload=function(){

resolve(img);

};

});

};

loadImg("https://images.unsplash.com/photo-1543363951-ec6198f35a38?auto=format&fit=crop&w=100&q=30")

.then(function(img){

var canvas=document.createElement("canvas");

var ctx=canvas.getContext("2d");

ctx.drawImage(img,0,0);

document.body.innerHTML='';

document.body.appendChild(canvas);

});

那能不能再简洁点呢?有个then在后面跟着看着也不太爽。而且我们在追求一行行的书写方式。这个时候就要用到 async/await 了,我们改写下:

async function loadImg(_url){

var img=new Image();

img.src=_url;

return new Promise(function(resolve, reject){

img.onload=function(){

resolve(img);

};

});

};

var img=await loadImg('https://images.unsplash.com/photo-1543363951-ec6198f35a38?auto=format&fit=crop&w=100&q=30');

var canvas=document.createElement("canvas");

var ctx=canvas.getContext("2d");

ctx.drawImage(img,0,0);

document.body.innerHTML='';

document.body.appendChild(canvas);

这下加载图片,可以用我们熟悉的“一行行”的写作方式了:

var img=await ...

....

ctx.drawImage(img,0,0);

return 优雅地写代码

   关于MIXLAB

MIXLAB 无界社区是一所面向未来的实验室,它提倡“跨界创新,开放成长”的理念。

——跨界 开放 互助 学习 思维 创新。

目前社区汇集了25000+跨学科人群,主要来自GoogleBrain、微软、华为、阿里鲁班、腾讯、旷视、三角兽、物灵科技、众安保险、美团、360等科技人才、设计师及CEO和投资人;

高校分布MIT、Oxford、Cambridge、CMU、UoM、清华、北大、复旦、上交大、同济等学生及教师群体;

学科跨越机器学习、自然语言处理、量化交易、物联网、区块链、前端、后端、产品经理、UI设计、建筑设计、服装设计、珠宝设计、音乐、艺术等。

详细介绍点击以下卡片:

mixlab期待您的加入!

让你具备无限可能……

(0)

相关推荐