Skip to main content

· 13 min read
0136yuntu

课代表来了(本视频所有概念也适用于其他异步编程的语言·): 

什么是异步编程

我们在执行一个长时间任务时,程序不需要等待,而是继续执行之后的代码。

     getUserPost();
// ...

直到程序执行完了之后再回来通知你,通常是以回调函数(callback)的形式。function(userPost){}就是回调函数。这种编程模式避免了程序的阻塞,提高了CPU的执行效率。尤其适用于IO密集的,例如经常需要进行网络操作,数据库访问的应用。以JS 为例介绍Promise, 以及新标准中优雅的async, await语法糖。

     getUserPost(function(userPost){
console.log(userPost);
});
// ...

JavaScript两种异步方式(单线程编程语言):

异步方法一

   - 传统回调函数 (Callback Function) 例如 setTimeOut , 在一个函数指定的时间后执行。这个函数本身会立刻返回。程序会紧接着执行之后的代码。而我们传入的回调函数则会等到预定的时间才会执行。需要主要的是JavaScript从设计之初就是单线程的,即便看上去这里的回调函数和主程序在并发执行,但他们都运行在同一个主线程上。 实际上主线程上还运行了其他代码,包括界面逻辑,网络请求,数据处理等等。

注释 这里的 ()=> {} 是箭头表达式,相当于函数定义的简化写法。

     setTimeout(()=>{   
console.log("好运!");
}3000);
console.log("紧接着执行我这条代码");
// ...
setTimeout 这个回调函数有一个明显的缺点,如果我们执行多个异步操作,我们的程序会一层一层的嵌套下去,可读性会变得非常差。
  • 回调函数缺点: 函数回调地狱 : 一个函数执行完在执行内部另外一个,一层一层嵌套, 视频1视频2

   - 单线程优点: 由于所有操作运行在一个线程中,无需考虑线程同步和资源竞争的开销,避免了线程之间的频繁切换和竞争问题,降低了开销

异步方法二

Promise (承诺) : 寓意这个去这个请求会在未来某一个时刻返回

Promise 解决了回调地狱的问题

JaveScript 中使用 Promise 的 API,fetch就是一个很好的例子。 例如: fetch 向服务器请求,返回Promise对象,渲染前端,如果可以使用then 进行接受 返回的结果

    fetch("https://www.woshishuaige.om").then((res)=>{
}) //它用来发起一个请求来获取服务器数据,我们可以用它来动态更新页面内容(也就是平常说的 AJAX-
// Asynchronous JavaScript and XML.

注释 https://jsonplaceholder.typicode.com 是一个用于测试假数据的API.

    fetch("https://jsonplaceholder.typicode.com/posts/1 ")  
fetch 访问上面哪个网站后,立刻返回一个 Promise {<pending>}对象, 承诺这个请求会在未来的某个时刻返回数据。
我们随后可以调用它的then 方法,并传递一个回调函数。 如果这个请求在未来成功完成,请求的结果也会以参数的形式(response)传递进来。
    fetch("https://jsonplaceholder.typicode.com/posts/1 ")
.then ((response)=>{})
但如果是这样,Promise和回调函数就没有区别了。其实Promise的优点在于它可以用一种链式结构(Chaining)将多个异步操作串联起来。比如下面程序的 response.json() 方法也会返回一个Promise. 它代表在未来的某个时刻将返回的数据转换成JSON格式。
    fetch("https://jsonplaceholder.typicode.com/posts/1 ")
.then ((response)=>response.json())
如果我们想等到它完成之后再执行其他的操作,我们可以在后面追加一个then.然后执行接下来的代码,比如将结果打印出来。Promise 的链式调用避免了代码的层层嵌套。即便我们有一个很长的链,代码也不过是向下方增长而非向右,因此可读性会提升很多。
    fetch("https://jsonplaceholder.typicode.com/posts/1 ")
.then ((response)=>response.json())
.then((json) => console.log(json));
使用异步操作的时候也可能会遇到错误。比如各种网络问题或返回的数据格式不正确等。如果我们要捕获这些错误,最简单的方法是附加一个 catch 在链式结构的末尾。如果之前任何一个阶段发生了错误,那么catch 将会被触发,而后的then()将不会执行。这和同步编程中遇到的 try...catch块很类似。
    fetch("https://jsonplaceholder.typicode.com/posts/1 ")
.then ((response)=>response.json())
.then((json) => {console.log(json);
})
.catch((error)=>{
console.error(error);
});
 Promise 还提供finally 方法。 它会在Promise 链结束之后调用。无论失败与否,我们可以在这里做一些清理工作。比如如果我们用到了加载动画,则可以在finally中关闭它。
    fetch("https://jsonplaceholder.typicode.com/posts/1 ")
.then ((response)=>response.json())
.then((json) => {console.log(json);
})
.catch((error)=>{
console.error(error);
})
.finally(()=>{
stopLoadingAnimation();
});

Promise优点:

我们可以用链式结构将多个异步操作串联起来如下

可以不断追加类似java8 stream,这样的链式调用避免了层层嵌套,一个人东西的出现一定是解决某类问题


fetch("https://www.woshishuaige.om").then((res)=>{

console.log(“我”)

}).then(res=>{

console.log(“是”)

}).then(res=>{

console.log(“你")

}).then(res=>{

console.log(“爹")

}).then(res=>{

console.log(“爹")

})

catch:

如果这样请求过程中某个戒断遇到错误,我们会触发catch,then将不会执行 ,类似 java 语法·


fetch("https://www.woshishuaige.om")
.then((res)=>{
console.log(“我”)
}).then(res=>{

console.log(“是”)

}).then(res=>{

console.log(“你")

}).then(res=>{

console.log(“爹")

}).then(res=>{

console.log(“爹")

}).catch(error=>{

console.log("如果程序报错了会输出我"+error)

})

``

finally

我们在请求过程中 如果有一段 必须要执行的代码可以放在 finally 中 ,学过java异常就是一样的道理

一般我们用来释放资源, 关闭声明请求,清理工作·

```js

fetch("https://www.woshishuaige.om").then((res)=>{

console.log(“我”)

}).then(res=>{

console.log(“是”)

}).then(res=>{

console.log(“你")

}).then(res=>{

console.log(“爹")

}).then(res=>{

console.log(“爹")

}).catch(error=>{

console.log("如果程序报错了会输出我"+error)

}).finally(()=>{

//

stopLoadingAnimation()

// Up 牛批

})

Javascript ECMA17 的新标准 async/ await

一句话概括:

语法糖,让异步操作变简单的,这两关键字基本同根同生, 被 async 修饰的 funcation 接受 请求必须用 await

首先我们要使用 async关键字将函数标记为异步函数。异步函数就是指返回值为Promise对象的函数。比如之前用到的fetch()就是一个异步函数。

async function f(){

}
f(); // 这个函数返回值永远是 Promise 对象。

在异步函数中我们可以调用其他的异步函数。不过我们不再需要使用then(), 而是使用一个更加简洁的await语法。await 会等待Promise完成之后直接返回最终的结果。所以下面程序的response已经是服务器返回的响应数据了。需要注意的是await虽然看上去会暂停函数的执行,但在执行的过程中,JavaScript同样可以处理其它的任务。比如更新界面,运行其他程序代码等。这是因为await底层是基于Promise和事件循环机制实现的。Promise + 事件循环(Event Loop).

async function f(){
const response = await fetc('https:///');
const json = await response.json();
console.log(json);
}
f();

await 使用时候的陷阱:

陷阱一: 下面的例子:如果我们分别去await这两个异步操作,虽然不存在逻辑错误,但这样写会打破这两个fetch()操作的并行。因为我们会等到第一个任务完成后才开始第二个任务。这里更高效的做饭时将所有Promise用 Promise.all 组合起来, 然后再去 await. 修改后的程序运行效率也会直接提升一倍。

async function f(){
const a = await fetc('https://.../post/1');
const b = await fetc('https://.../post/2');
}
f();
async function f(){
const promiseA = await fetc('https://.../post/1');
const promiseB = await fetc('https://.../post/2');

const [a, b]= await Promise.all([promiseA, promiseB]);
}
f();

陷阱二: 如果我们需要在循环中执行异步操作,时不能够直接调用forEach 或者 map 这一类方法的。尽管在下面的函数中写了await, 但这里的forEach 会立刻返回,它并不会等到所有的异步操作都执行完毕。

async function f(){
[1, 2, 3].forEach(async(i)=>{
await someAsyncOperation();
});
console.log("done")
}
f();

如果我们希望等待循环中的异步操作都 一 一 完成之后才继续执行,那我们还是应当使用传统的for循环。

async function f(){
for (let i of [1, 2, 3]){
await someAsyncOperation();
})
console.log("done");
}
f();

更进一步,如果我们想要循环中的所有操作都并发执行,一种更炫酷的方法时使用 for await. 这里的 for 循环依然会等到所有的异步操作都完成后才继续向后执行。

async funcation f(){

const promises =[

someAsyncOperator();
someAsyncOperator();
someAsyncOperator();

];
for await (let result of promises){
}
console.log("done");
}

陷阱三: 我们不能在全局或者普通函数中直接使用await关键字。await 只能被用在异步函数(async function)中。 如果我们想在最外层中使用await, 那么需要先定义一个异步函数,然后在函数体中使用它。

多个Promise 使用时会打破并行,

第一个执行完才执行第二个,高效做法:

Promise.all内可以传递多个promise对象

然后再使用await ,效率会提升一倍

const [a,b]= await Promise.all([promiseA,promiseB])

如果想使用 循环中的 所有操作都并发执行可以使用 for await


async funcation f(){

const promises =[

someAsyncOperator();

someAsyncOperator();

someAsyncOperator();

];

for await (let result of promises){



}



}

不能在全局和 普通函数 中使用 await关键字,只能被应用异步,所以想要使用 await 就必须 用 async修饰函数

所以说就跟你对象一样 ,必须相互配合才能完成一些事情

作者:0136云图 https://www.bilibili.com/read/cv13486386 出处:bilibili

· 29 min read
Collective Creation
  1. Node.js是用来做什么的?
  2. npm 是干什么的?(非教程)
  3. Yarn是什么?
  4. Yarn yarn.lock文件
  5. npm和yarn的区别,我们该如何选择?
  6. Babel 是什么?
  7. cname记录是什么?他存在的意义是什么?

Node.js是用来做什么的?

回答 1:

一种javascript的运行环境,能够使得javascript脱离浏览器运行。

回答 2:

国外有一篇非常好的Node.js 介绍文章,从原理入手讲解,在这里给大家翻译一下(本人非翻译出身,一些地方结合了点个人理解,有错误欢迎指出)。原文地址 Node.js is the New Black 译文如下: 如果你去年注意过技术方面的新闻,我敢说你至少看到node.js不下一两次。那么问题来了“node.js是什么?”。有些人没准会告诉你“这是一种通过JavaScript语言开发web服务端的东西”。如果这种晦涩解释还没把你搞晕,你没准会接着问:“为什么我们要用node.js?”,别人一般会告诉你:node.js有非阻塞,事件驱动I/O等特性,从而让高并发(high concurrency)在的轮询(Polling)和comet构建的应用中成为可能。当你看完这些解释觉得跟看天书一样的时候,你估计也懒得继续问了。不过没事。我这篇文章就是在避开高端术语的同时,帮助你你理解node.js的。浏览器给网站发请求的过程一直没怎么变过。当浏览器给网站发了请求。服务器收到了请求,然后开始搜寻被请求的资源。如果有需要,服务器还会查询一下数据库,最后把响应结果传回浏览器。不过,在传统的web服务器中(比如Apache),每一个请求都会让服务器创建一个新的进程来处理这个请求。后来有了Ajax。有了Ajax,我们就不用每次都请求一个完整的新页面了,取而代之的是,每次只请求需要的部分页面信息就可以了。这显然是一个进步。但是比如你要建一个FriendFeed这样的社交网站(类似人人网那样的刷朋友新鲜事的网站),你的好友会随时的推送新的状态,然后你的新鲜事会实时自动刷新。要达成这个需求,我们需要让用户一直与服务器保持一个有效连接。目前最简单的实现方法,就是让用户和服务器之间保持长轮询(long polling)。HTTP请求不是持续的连接,你请求一次,服务器响应一次,然后就完了。长轮训是一种利用HTTP模拟持续连接的技巧。具体来说,只要页面载入了,不管你需不需要服务器给你响应信息,你都会给服务器发一个Ajax请求。这个请求不同于一般的Ajax请求,服务器不会直接给你返回信息,而是它要等着,直到服务器觉得该给你发信息了,它才会响应。比如,你的好友发了一条新鲜事,服务器就会把这个新鲜事当做响应发给你的浏览器,然后你的浏览器就刷新页面了。浏览器收到响应刷新完之后,再发送一条新的请求给服务器,这个请求依然不会立即被响应。于是就开始重复以上步骤。利用这个方法,可以让浏览器始终保持等待响应的状态。虽然以上过程依然只有非持续的Http参与,但是我们模拟出了一个看似持续的连接状态我们再看传统的服务器(比如Apache)。每次一个新用户连到你的网站上,你的服务器就得开一个连接。每个连接都需要占一个进程,这些进程大部分时间都是闲着的(比如等着你好友发新鲜事,等好友发完才给用户响应信息。或者等着数据库返回查询结果什么的)。虽然这些进程闲着,但是照样占用内存。这意味着,如果用户连接数的增长到一定规模,你服务器没准就要耗光内存直接瘫了。这种情况怎么解决?解决方法就是刚才上边说的:非阻塞和事件驱动。这些概念在我们谈的这个情景里面其实没那么难理解。你把非阻塞的服务器想象成一个loop循环,这个loop会一直跑下去。一个新请求来了,这个loop就接了这个请求,把这个请求传给其他的进程(比如传给一个搞数据库查询的进程),然后响应一个回调(callback)。完事了这loop就接着跑,接其他的请求。这样下来。服务器就不会像之前那样傻等着数据库返回结果了。如果数据库把结果返回来了,loop就把结果传回用户的浏览器,接着继续跑。在这种方式下,你的服务器的进程就不会闲着等着。从而在理论上说,同一时刻的数据库查询数量,以及用户的请求数量就没有限制了。服务器只在用户那边有事件发生的时候才响应,这就是事件驱动。FriendFeed是用基于Python的非阻塞框架Tornado (知乎也用了这个框架) 来实现上面说的新鲜事功能的。不过,Node.js就比前者更妙了。Node.js的应用是通过javascript开发的,然后直接在Google的变态V8引擎上跑。用了Node.js,你就不用担心用户端的请求会在服务器里跑了一段能够造成阻塞的代码了。因为javascript本身就是事件驱动的脚本语言。你回想一下,在给前端写javascript的时候,更多时候你都是在搞事件处理和回调函数。javascript本身就是给事件处理量身定制的语言。Node.js还是处于初期阶段。如果你想开发一个基于Node.js的应用,你应该会需要写一些很底层代码。但是下一代浏览器很快就要采用WebSocket技术了,从而长轮询也会消失。在Web开发里,Node.js这种类型的技术只会变得越来越重要。

回答 3: 作者:张戎 链接:https://www.zhihu.com/question/33578075/answer/252611915 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

阅读本帖需要先复习小学语文课文,华罗庚的《统筹方法》。比如,想泡壶茶喝。当时的情况是:开水没有;水壶要洗,茶壶茶杯要洗;火生了,茶叶也有了。怎么办? 办法甲:洗好水壶,灌上凉水,放在火上;在等待水开的时间里,洗茶壶、洗茶杯、拿茶叶;等水开了,泡茶喝。 办法乙:先做好一些准备工作,洗水壶,洗茶壶茶杯,拿茶叶;一切就绪,灌水烧水;坐待水开了泡茶喝。 办法丙:洗净水壶,灌上凉水,放在火上,坐待水开;水开了之后,急急忙忙找茶叶,洗茶壶茶杯,泡茶喝。 哪一种办法省时间?我们能一眼看出第一种办法好,后两种办法都窝了工。... 从这个图上可以一眼看出,办法甲总共要16分钟(而办法乙、丙需要20分钟)。...看来这是“小题大做”,但在工作环节太多的时候,这样做就非常有必要了。...来源:华罗庚 统筹方法_百度文库Node.js就是跟华罗庚一伙的,帮助我们更快地沏茶,而且更快地给一帮人沏茶。我们在用浏览器访问服务器的时候,就好像去茶叶铺买茶喝。我们可以买回来自己沏,也可以在店里自带的茶座儿坐下来喝现成的。如果我们买回来喝,参考华老师的课文,他自己都说了这是「小题大作」,因为16分钟和20分钟差不了太多,就我们自己和家人,慢生活4分钟也没什么毛病。但是如果我们在店里喝,那可不是咱一家儿等着。比起16分钟的最少等候时间,第一桌多等4分钟,第二桌要同时来的话得多等24分钟,第三桌站起来走了,20多张桌子都闲着。忙活了半天,茶客不耐烦,茶铺不赚钱。所以,茶叶铺一定要学好小学课文,不仅对于同一桌的不同请求要统筹安排,别认死理一件事不干完绝不开始下一件,甚至对于不同桌的不同请求也要尽量并行处理,比如等开水时可以帮好几桌点单、拿茶叶、洗茶杯茶壶,水开之前别闲着,水一开就给各桌上茶,让每桌客人都感觉嗖快嗖快的。

在这个故事里,茶叶铺就是网络服务器。我们自己就是浏览器。我们要是不想浏览器事必躬亲,那就把活扔给服务器干;当服务器一下子服务很多浏览器时就不能认死理非要串行操作,要灵活统筹,同时开始几件事,哪件完事关闭哪件。

这三个特征用江湖切口说就叫:

  • 服务器端JavaScript处理:server-side JavaScript execution
  • 非阻断/异步I/O:non-blocking or asynchronous I/O
  • 事件驱动:Event-driven Node.js 就是这样一个服务器端的、非阻断式I/O的、事件驱动的JavaScript运行环境。所以说,Node.js是华罗庚的路数,帮茶叶铺更快更多地伺候茶客。这麻利的店小二谁家养的?大家。因为Node.js是开源的。

原始链接:https://www.zhihu.com/question/33578075

npm 是干什么的?(非教程)

社区 程序员自古以来就有社区文化:

社区的意思是:拥有共同职业或兴趣的人们,自发组织在一起,通过分享信息和资源进行合作。虚拟社区的参与者经常会在线讨论相关话题,或访问某些网站。 前端程序员也有社区,世界上最大的前端社区应该就是 GitHub 了。前端通过 GitHub 来

分享源代码(线上代码仓库) 讨论问题(Issue 列表) 收集学习资源和常去的网站(比如我收集的优质中文前端博客)

加入社区最大的好处之一是,你可以使用别人贡献的代码,你也可以贡献代码给别人用。

麻烦 当一个网站依赖的代码越来越多,程序员发现这是一件很麻烦的事情:

去 jQuery 官网下载 jQuery 去 BootStrap 官网下载 BootStrap 去 Underscore 官网下载 Underscore ……

有些程序员就受不鸟了,一个拥有三大美德的程序员 Isaac Z. Schlueter (以下简称 Isaaz)给出一个解决方案:用一个工具把这些代码集中到一起来管理吧!

这个工具就是他用 JavaScript (运行在 Node.js 上)写的 npm,全称是 Node Package Manager

具体步骤 NPM 的思路大概是这样的:

  1. 买个服务器作为代码仓库(registry),在里面放所有需要被共享的代码

  2. 发邮件通知 jQuery、Bootstrap、Underscore 作者使用 npm publish 把代码提交到 registry 上,分别取名 jquery、bootstrap 和 underscore(注意大小写)

  3. 社区里的其他人如果想使用这些代码,就把 jquery、bootstrap 和 underscore 写到 package.json 里,然后运行 npm install ,npm 就会帮他们下载代码

  4. 下载完的代码出现在 node_modules 目录里,可以随意使用了。

这些可以被使用的代码被叫做「包」(package),这就是 NPM 名字的由来:Node Package(包) Manager(管理器)。

发展 Isaaz 通知 jQuery 作者 John Resig,他会答应吗?这事儿不一定啊,对不对。

只有社区里的人都觉得 「npm 是个宝」的时候,John Resig 才会考虑使用 npm。

那么 npm 是怎么火的呢?

npm 的发展是跟 Node.js 的发展相辅相成的。

Node.js 是由一个在德国工作的美国程序员 Ryan Dahl 写的。他写了 Node.js,但是 Node.js 缺少一个包管理器,于是他和 npm 的作者一拍即合、抱团取暖,最终 Node.js 内置了 npm。

后来的事情大家都知道,Node.js 火了。

随着 Node.js 的火爆,大家开始用 npm 来共享 JS 代码了,于是 jQuery 作者也将 jQuery 发布到 npm 了。

所以现在,你可以使用 npm install jquery 来下载 jQuery 代码。

现在用 npm 来分享代码已经成了前端的标配。

后续 Node.js 目前由 Ryan Dahl 当时所在的公司 joyent 继续开发。Ryan Dahl 现在已经去研究 AI 和机器学习了,并且他把 Node.js 的维护权交给了 Isaaz。(我是不是也应该去研究 AI 和机器学习啊教练)

而 Isaaz 维护了一段时间后,辞职了,成立了一个公司专门维护 npm 的 registry,公司名叫做 npm 股份有限公司……谁说开源不能赚钱的~

原始链接:https://zhuanlan.zhihu.com/p/24357770

Yarn是什么?

姓名:岳沁  学号:17101223458

转载自:https://yarnpkg.com/zh-Hans/docs/usage

Yarn 对你的代码来说是一个包管理器, 你可以通过它使用全世界开发者的代码,或者分享自己的代码。 Yarn 做这些快捷、安全、可靠,所以你不用担心什么。

通过Yarn你可以使用其他开发者针对不同问题的解决方案,使自己的开发过程更简单。 使用过程中遇到问题,你可以将其上报或者贡献解决方案。一旦问题被修复,Yarn会更新保持同步。

代码通过包(package)(或者称为模块(module))的方式来共享。 一个包里包含所有需要共享的代码,以及描述包信息的文件,称为package.json。

作者:丘之心 原始链接:https://www.jianshu.com/p/1e8510826703

Yarn yarn.lock文件

为了在多台机器之间获得一致的安装结果,Yarn 可能会需要比 package.json 文件中配置的依赖项更多的信息。它需要准确存储每一个依赖项的安装版本。因此在 Yarn 项目的根目录我们需要一个 yarn.lock 文件,这个 yarn.lock 文件是自动生成的。

当我们执行 yarn 命令或者添加依赖包命令后,Yarn 都会在项目根目录下自动生成一个 yarn.lock 文件。在使用 Yarn 安装、升级、删除依赖项目时,会自动更新到 yarn.lock 文件中。一般我们不会去手动编辑这个文件,因为很容易破坏这个文件。

示例: 例如我们安装了一些依赖包,那么 yarn.lock 文件内容类似所示格式:

copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=

create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== dependencies: bn.js "^4.1.0" elliptic "^6.0.0"

可以明显看到 yarn.lock 文件中的信息比 package.json 文件中详细了很多。

在实际项目中,yarn.lock 文件也很有用处,我们可以将 yarn.lock 提交到版本库中,其他成员就可以通过 yarn install 获取所有依赖包,这个可以保证大家安装的依赖是完全一致的,避免产生 bug。

原文链接:https://segmentfault.com/a/1190000039820351

npm和yarn的区别,我们该如何选择?

Yarn是什么? “Yarn是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 ,正如官方文档中写的,Yarn 是为了弥补 npm 的一些缺陷而出现的。”这句话让我想起了使用npm时的坑了:

  • npm install的时候巨慢。特别是新的项目拉下来要等半天,删除node_modules,重新install的时候依旧如此。
  • 同一个项目,安装的时候无法保持一致性。由于package.json文件中版本号的特点,下面三个版本号在安装的时候代表不同的含义。

"5.0.3", "~5.0.3", "^5.0.3" “5.0.3”表示安装指定的5.0.3版本,“~5.0.3”表示安装5.0.X中最新的版本,“^5.0.3”表示安装5.X.X中最新的版本。这就麻烦了,常常会出现同一个项目,有的同事是OK的,有的同事会由于安装的版本不一致出现bug。

  • 安装的时候,包会在同一时间下载和安装,中途某个时候,一个包抛出了一个错误,但是npm会继续下载和安装包。因为npm会把所有的日志输出到终端,有关错误包的错误信息就会在一大堆npm打印的警告中丢失掉,并且你甚至永远不会注意到实际发生的错误。

带着这些坑,我开始了解Yarn的优势及其解决的问题。

Yarn的优点? 速度快 。速度快主要来自以下两个方面: 并行安装:无论 npm 还是 Yarn 在执行包的安装时,都会执行一系列任务。npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。而 Yarn 是同步执行所有任务,提高了性能。 离线模式:如果之前已经安装过一个软件包,用Yarn再次安装时之间从缓存中获取,就不用像npm那样再从网络下载了。 安装版本统一:为了防止拉取到不同的版本,Yarn 有一个锁定文件 (lock file) 记录了被确切安装上的模块的版本号。每次只要新增了一个模块,Yarn 就会创建(或更新)yarn.lock 这个文件。这么做就保证了,每一次拉取同一个项目依赖时,使用的都是一样的模块版本。npm 其实也有办法实现处处使用相同版本的 packages,但需要开发者执行 npm shrinkwrap 命令。这个命令将会生成一个锁定文件,在执行 npm install 的时候,该锁定文件会先被读取,和 Yarn 读取 yarn.lock 文件一个道理。npm 和 Yarn 两者的不同之处在于,Yarn 默认会生成这样的锁定文件,而 npm 要通过 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有当这个文件存在的时候,packages 版本信息才会被记录和更新。 更简洁的输出:npm 的输出信息比较冗长。在执行 npm install 的时候,命令行里会不断地打印出所有被安装上的依赖。相比之下,Yarn 简洁太多:默认情况下,结合了 emoji直观且直接地打印出必要的信息,也提供了一些命令供开发者查询额外的安装信息。 多注册来源处理:所有的依赖包,不管他被不同的库间接关联引用多少次,安装这个包时,只会从一个注册来源去装,要么是 npm 要么是 bower, 防止出现混乱不一致。 更好的语义化: yarn改变了一些npm命令的名称,比如 yarn add/remove,感觉上比 npm 原本的 install/uninstall 要更清晰。 Yarn和npm命令对比 npm install === yarn npm install taco --save === yarn add taco npm uninstall taco --save === yarn remove taco npm install taco --save-dev === yarn add taco --dev npm update --save === yarn upgrade npm的未来:npm5.0 有了yarn的压力之后,npm做了一些类似的改进。

  1. 默认新增了类似yarn.lock的 package-lock.json;
  2. git 依赖支持优化:这个特性在需要安装大量内部项目(例如在没有自建源的内网开发),或需要使用某些依赖的未发布版本时很有用。在这之前可能需要使用指定 commitid 的方式来控制版本。
  3. 文件依赖优化:在之前的版本,如果将本地目录作为依赖来安装,将会把文件目录作为副本拷贝到 nodemodules 中。而在 npm5 中,将改为使用创建 symlinks 的方式来实现(使用本地 tarball 包除外),而不再执行文件拷贝。这将会提升安装速度。目前yarn还不支持。

总结

在npm5.0之前,yarn的优势特别明显。但是在npm之后,通过以上一系列对比,我们可以看到 npm5 在速度和使用上确实有了很大提升,值得尝试,不过还没有超过yarn。

综上我个人的建议是如果你已经在个人项目上使用 yarn,并且没有遇到更多问题,目前完全可以继续使用。但如果有兼容 npm 的场景,或者身处在使用 npm,cnpm,tnpm 的团队,以及还没有切到 yarn 的项目,那现在就可以试一试 npm5 了。

原文链接:https://zhuanlan.zhihu.com/p/27449990

Babel 是什么?

Babel 是一个 JavaScript 编译器 Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。下面列出的是 Babel 能为你做的事情:

语法转换 通过 Polyfill 方式在目标环境中添加缺失的特性 (通过引入第三方 polyfill 模块,例如 core-js) 源码转换(codemods) 更多参考资料!(请查看这些 视频 以获得启发) 原始链接:https://www.babeljs.cn/docs/

cname记录是什么?他存在的意义是什么?

使用A记录和CNAME进行域名解析的区别A记录就是把一个域名解析到一个IP地址(Address,特制数字IP地址),而CNAME记录就是把域名解析到另外一个域名。其功能是差不多,CNAME将几个主机名指向一个别名,其实跟指向IP地址是一样的,因为这个别名也要做一个A记录的。但是使用CNAME记录可以很方便地变更IP地址。如果一台服务器有100个网站,他们都做了别名,该台服务器变更IP时,只需要变更别名的A记录就可以了。

原始链接:https://www.zhihu.com/question/22916306/answer/26650717

· 7 min read
Pierrotle Fou

YAML和JSON有什么区别?什么时候比较喜欢一个 从技术上讲,YAML是JSON的超集。这意味着,至少在理论上,YAML解析器可以理解JSON,但不一定相反。

请参阅官方规范,标题为 “YAML:与JSON的关系” 。

一般来说,我喜欢YAML中某些JSON中没有的东西。

As @jdupont指出 ,YAML在视觉上更容易看。事实上, YAML主页 本身就是有效的YAML,但人们很容易阅读。 YAML能够使用“锚点”引用YAML文件中的其他项目。因此,它可以处理MySQL数据库中可能找到的关系信息。 YAML在嵌入其他序列化格式(如JSON或XML within YAML文件)方面更加强大。 实际上,最后两点都不会对你或我所做的事情产生影响,但从长远来看,我认为YAML将是一种更强大和可行的数据序列化格式。

现在,AJAX和其他Web技术倾向于使用JSON。 YAML目前更多地用于离线数据处理。例如,它默认包含在基于C的OpenCV计算机视觉包中,而JSON则不包括在内。

您将找到JSON和YAML的C库。 YAML的图书馆往往更新,但我过去没有遇到任何问题。参见例如 Yaml-cpp

区别:

  • YAML,取决于您如何使用它,可以比JSON更具可读性
  • JSON经常 更快 并且可能仍然可以与更多系统互操作
  • 可以非常快速地编写一个“足够好”的JSON解析器
  • 重复键是 可能 有效JSON,是 肯定 无效YAML。
  • YAML有很多功能,包括评论和关系锚。因此,YAML语法非常复杂,并且很难理解。
  • 可以在yaml中编写递归结构:{a: &b [*b]},它将在某些转换器中无限循环。即使使用循环检测,仍然可以使用“yaml炸弹”(参见 xml炸弹 )。
  • 因为没有引用,所以不可能在JSON中使用对象引用序列化复杂结构。因此,YAML序列化可以更有效。
  • 在某些编码环境中,使用YAML可以允许攻击者执行 执行任意代码 。

观察:

  • Python程序员通常是YAML的忠实粉丝,因为使用缩进而不是括号语法来指示级别。
  • 许多程序员认为将“意义”作为缩进的依附是一个糟糕的选择。
  • 如果数据格式将离开应用程序的环境,在UI中解析或在消息传递层中发送,则JSON可能是更好的选择。
  • YAML可以直接用于语法定义等复杂任务,并且通常比发明新语言更好。

绕过深奥的理论:

这回答标题,而不是详细信息,因为大多数人只是像谷歌一样从google搜索结果中读取标题,所以我觉得有必要解释从网站开发者的角度来看。

YAML使用空格缩进,这是Python开发人员熟悉的领域。 JavaScript开发人员喜欢JSON,因为它是JavaScript的一个子集,可以直接在JavaScript中解释和编写,同时使用简写方式声明JSON,在使用没有空格的典型变量名时,不需要键中的双引号。 有很多解析器在YAML和JSON的所有语言中都能很好地工作。 在许多情况下,YAML的空白格式可以更容易查看,因为格式化需要更人性化的方法。 如果您的编辑器中没有空格可见或缩进线指示符,那么YAML的空白虽然更紧凑,更容易查看,但可能难以手动编辑。 JSON的序列化和反序列化要快得多,因为要检查的功能明显少于YAML,这使得更小更轻的代码能够处理JSON。 一个常见的误解是YAML需要更少的标点符号并且比JSON更紧凑,但这完全是错误的。空格是不可见的,所以看起来字符较少,但是如果你计算实际的空格是必要的,以便正确解释YAML以及正确的缩进,你会发现YAML实际上需要比JSON更多的字符。 JSON不使用空格来表示层次结构或分组,并且可以通过删除不必要的空格来轻松展平,以实现更紧凑的传输。 房间里的大象:互联网本身 JavaScript如此明显地占据了网络的巨大优势,而JavaScript开发人员更喜欢将JSON作为数据格式与流行的Web API一起使用,因此在进行一般意义上的Web编程时,很难使用YAML而不是JSON,因为您可能会被淘汰在团队环境中。实际上,大多数Web程序员甚至都不知道YAML存在,更不用说考虑使用它了。

如果您正在进行任何Web编程,JSON是默认的方法,因为在使用JavaScript时不需要转换步骤,因此在这种情况下您必须提出更好的参数来使用YAML而不是JSON。

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

· 5 min read
Louis Simoneau

If you’ve been paying attention to news about web technology in the last year, you’ve most likely heard the name node.js mentioned at least once or twice. What happened next probably went like this: you asked, “What is it?” and someone (or Google) told you that it was a way to write web servers using JavaScript. If that didn’t scare you away, you might then have asked, “Why would you want to use it?” and the answer might have been along the lines of it taking advantage of non-blocking, event-driven IO to enable high concurrency in long polling or comet-based applications.

At which point you stopped asking questions. I don’t blame you. To help break apart that wall of jargon, here’s my attempt at explaining what node.js is and why you should be paying attention to it.

So here’s how it is, how it’s always been: a browser sends a request to a website. The site’s server receives the request, tracks down the requested file, performs any database queries as needed, and sends a response to the browser. In traditional web servers, such as Apache, each request causes the server to create a new system process to handle that request.

Then there was Ajax. Instead of requesting a whole new page each time, we’d only request the piece of information we actually wanted. Okay, that’s an improvement.

But now think about how you’d go about building a service like FriendFeed, where each user’s feed is updating in real time, all the time. The only way that’s possible is if each user has an active connection to the server at all times. The simplest way to do that at present is through long polling.

Long polling essentially tricks HTTP into acting like a persistent connection: as soon as the page loads, it fires off an Ajax request to the server, even if the page doesn’t want anything in particular. But, unlike a normal Ajax request, the server doesn’t respond right away. It just waits, and fires back a response only when it has something new it wants the browser to display. For example, as soon as one of your friends adds a new post, the server returns the response telling the browser to update its display. As soon as the browser receives the response, it shoots back another request. This way the browser is always waiting for a new event to happen on the server side.

Now think about what that means for a traditional web server like Apache. For each and every user connected to the site, your server has to keep a connection open. Each connection requires a process, and each of those processes will spend most of its time either sitting idle (consuming memory) or waiting on a database query to complete. This means that it’s hard to scale up to high numbers of connections without grinding to a near halt and using up all your resources.

So what’s the solution? Here’s where some of that jargon from before comes into play: specifically non-blocking and event-driven. What those terms mean in this context is less complicated than you might fear. Think of a non-blocking server as a loop: it just keeps going round and round. A request comes in, the loop grabs it, passes it along to some other process (like a database query), sets up a callback, and keeps going round, ready for the next request. It doesn’t just sit there, waiting for the database to come back with the requested info.

If the database query comes back — fine, we’ll deal with that the same way: throw a response back to the client and keep looping around. There’s theoretically no limit on how many database queries you can be waiting on, or how many clients have open requests, because you’re not spending any time waiting for them. You deal with them all in their own time, and that’s what event-driven means: the server only reacts when an event occurs. That could be a request, a file being loaded, or a query being executed — it really doesn’t matter.

FriendFeed uses a non-blocking framework written in Python, called Tornado, to do this. The nginx web server also behaves in this way. Node.js, however, has an ace up its sleeve: because it’s using JavaScript — running on Google’s crazy-fast V8 engine — it never needs to worry about whether a request it makes to another piece of code might cause the loop to block up. The reason is that JavaScript is intrinsically event-driven. Think about it: when you write JavaScript for the browser, you’re just attaching event handlers and callbacks. That’s the way the language was designed.

Node.js is still in its infancy, so if you want to write an application based on it you’ll need to do some fairly low-level coding. But with the impending arrival of WebSockets in next-generation browsers (eliminating the need for long polling altogether), this type of technology will only become more important on the Web. I hope I’ve given you the incentive to start messing around and getting your head around these concepts.

Translation:https://www.zhihu.com/question/33578075/answer/56951771