//…

var f = yield readFile(fileA);

//…

}

通过一个 Generator 函数的 yield, 可以将一个协程中断,去执行另一个协程。我们可以换一个角度理解 Generator 函数:它是协程在 ES6 中的具体体现。我们可以简单写一个异步任务的封装:

var fetch = require(‘node-fetch’);

function* gen(){

var url = ‘http://api.github.com/users/github’;

var result = yield fetch(url);

console.log(result.bio);

}

var g = gen();

var result = g.next(); //返回的 value 是一个 Promise 对象

result.value.then(function(data){

return data.json;

}).then(function(data){

g.next(data);

});

Thunk 函数

在函数传参数时我们考虑这样一个问题:

function fun(x){

return x + 5;

}

var a = 10;

fun(a + 10);

这个函数返回25肯定没错,但是,我们传给函数 fun 的参数在编译时到底保留 a + 10 还是直接传入 20?显然前者没有事先计算,如果函数内多次使用这个参数,就会产生多次计算,影响性能;而后者事先计算了,但如果函数里不使用这个变量就白浪费了性能。采用把参数原封不动的放入一个函数(我们将这个函数称为 Thunk 函数),用的使用调用该函数的方式。也就是上面的前一种方式传值。所以上面代码等价于:

function fun(x){

return x() + 5;

}

var a = 10;

var thunk = function(){ return a + 10};

fun(thunk);

**但是 js 不是这样的!**js 会把多参数函数给 Thunk 了,以减少参数:

var fs = require(‘fs’);

fs.readFile(fileName, callback);

var readFileThunk = Thunk(fileName);

readFileThunk(callback);

var Thunk = function(fileName){

return function(callback){

return fs.readFile(fileName,callback);

};

};

这里任何具有回调函数的函数都可以写成这样的 Thunk 函数,方法如下:

function Thunk(fn){

return function(){

var args = Array.prototype.slice.call(arguments);

return function (callback){

args.push(callback);

return fn.apply(this, args);

}

}

}

//这样fs.readFile(fileName, callback); 写作如下形式

Thunk(fs.readFile)(fileName)(callback);

关于 Thunk 函数, 可以直接使用 thunkify 模块:

npm install thunkify

使用格式和上面的Thunk(fs.readFile)(fileName)(callback);一致,但使用过程中需要注意,其内部加入了检查机制,只允许 callback 被回调一次!

结合 Thunk 函数和协程,我们可以实现自动流程管理。之前我们使用 Generator 时候使用 yield 关键字将 cpu 资源释放,执行移出 Generator 函数。可以怎么移回来呢?之前我们手动调用 Generator 返回的迭代器的 next() 方法,可这毕竟是手动的,现在我们就利用 Thunk 函数实现一个自动的:

var fs = require(‘fs’);

var thunkify = require(‘thunkify’);

var readFile = thunkify(fs.readFile);

var gen = function*(…args){ //args 是文件路径数组

for(var i = 0, len = args.length; i < len; i++){

var r = yield readFile(args[i]);

console.log(r.toString());

}

};

(function run(fn){

var gen = fn();

function next(err, data){

if(err) throw err;

var result = gen.next(data);

if(result.done) return; //递归直到所以文件读取完成

result.value(next); //递归执行

}

next();

})(gen);

//之后可以使用 run 函数继续读取其他文件操作

如果说 Thunk 可以有现成的库使用,那么这个自动执行的 Generator 函数也有现成的库可以使用——co模块(https://github.com/tj/co)。用法与上面类似,不过 co 模块返回一个 Promise 对象。使用方式如下:

var co = require(‘co’);

var fs = require(‘fs’);

var thunkify = require(‘thunkify’);

var readFile = thunkify(fs.readFile);

var gen = function*(…args){ //args 是文件路径数组

for(var i = 0, len = args.length; i < len; i++){

var r = yield readFile(args[i]);

console.log(r.toString());

}

};

co(gen).then(function(){

console.log(“files loaded”);

}).catch(function(err){

console.log(“load fail”);

});

这里需要注意的是:yield 后面只能跟一个 thunk 函数或 promise 对象。上例中第8行 yield 后面的 readFile 是一个 thunk 函数,所以可以使用。

上面已经讲解了 thunk 函数实现自动流程管理,下面使用 Promise 实现一下:

var fs = require(‘fs’);

var readFile = function(fileName){

return new Promise(function(resolve, reject){

fs.readFile(fileName, function(error,data){

if(error) reject(error);

resolve(data);

});

});

};

var gen = function*(){

for(var i = 0, len = args.length; i < len; i++){

var r = yield readFile(args[i]);

console.log(r.toString());

}

};

(function run(gen){

var g = gen();

var resolve = function(data){

var result = g.next(data);

if(result.done) return result.value;

result.value.then(resolve);

}

g.next().value.then(function(data){

resolve(data);

});

resolve();

})(gen);

//之后可以使用 run 函数继续读取其他文件操作

async 函数

ES7 中提出了 async 函数,但是现在已经可以用了!可这个又是什么呢?其实就是 Generator 函数的改进,我们上文写过一个这样的 Generator 函数:

var gen = function*(){

for(var i = 0, len = args.length; i < len; i++){

var r = yield readFile(args[i]);

console.log(r.toString());

}

};

我们把它改写成 async 函数:

var asyncReadFiles = async function(){ //* 替换为 async

for(var i = 0, len = args.length; i < len; i++){

var r = await readFile(args[i]); //yield 替换为 await

console.log(r.toString());

}

};

async 函数对 Generator 函数做了一下改进:

  • Generator 函数需要手动通过返回值的 next 方法执行,而 async 函数自带执行器,执行方式和普通函数完全一样。

var result = asyncReadFiles(fileA, fileB, fileC);

  • 语义明确,async 表示异步,await 表示后续表达式需要等待触发的异步操作结束

  • co 模块中 yield 后面只能跟一个 thunk 函数或 promise 对象,而 await 后面可以是任何类型(不是 Promise 对象就同步执行)

  • 返回值是一个 Promise 对象,不是 Iterator ,比 Generator 方便

我们可以实现这样的一个 async 函数:

async function asyncFun(){

//code here

}

//equal to…

function asyncFun(args){

return fun(function*(){

//code here…

});

function fun(genF){

return new Promise(function(resolve, reject){

var gen = genF();

function step(nextF){

try{

var next = nextF();

} catch(e) {

return reject(e);

}

if(next.done){

return resolve(next.value);

}

Promise.resolve(next.value).then(function(data){

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

下面是我在学习HTML和CSS的时候整理的一些笔记,有兴趣的可以看下:

HTML、CSS部分截图

进阶阶段

进阶阶段,开始攻 JS,对于刚接触 JS 的初学者,确实比学习 HTML 和 CSS 有难度,但是只要肯下功夫,这部分对于你来说,也不是什么大问题。

JS 内容涉及到的知识点较多,看到网上有很多人建议你从头到尾抱着那本《JavaScript高级程序设计》学,我是不建议的,毕竟刚接触 JS 谁能看得下去,当时我也不能,也没那样做。

我这部分的学习技巧是,增加次数,减少单次看的内容。就是说,第一遍学习 JS 走马观花的看,看个大概,去找视频以及网站学习,不建议直接看书。因为看书看不下去的时候很打击你学下去的信心。

然后通过一些网站的小例子,开始动手敲代码,一定要去实践、实践、实践,这一遍是为了更好的去熟悉 JS 的语法。别只顾着来回的看知识点,眼高手低可不是个好习惯,我在这吃过亏,你懂的。

1、JavaScript 和 ES6

在这个过程你会发现,有很多 JS 知识点你并不能更好的理解为什么这么设计,以及这样设计的好处是什么,这就逼着让你去学习这单个知识点的来龙去脉,去哪学?第一,书籍,我知道你不喜欢看,我最近通过刷大厂面试题整理了一份前端核心知识笔记,比较书籍更精简,一句废话都没有,这份笔记也让我通过跳槽从8k涨成20k。

JavaScript部分截图

2、前端框架

前端框架太多了,真的学不动了,别慌,其实对于前端的三大马车,Angular、React、Vue 只要把其中一种框架学明白,底层原理实现,其他两个学起来不会很吃力,这也取决于你以后就职的公司要求你会哪一个框架了,当然,会的越多越好,但是往往每个人的时间是有限的,对于自学的学生,或者即将面试找工作的人,当然要选择一门框架深挖原理。

以 Vue 为例,我整理了如下的面试题。

Vue部分截图

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

s://img-blog.csdnimg.cn/img_convert/cac778dc45492a41e2f3e7cd6b0134e5.png)

2、前端框架

前端框架太多了,真的学不动了,别慌,其实对于前端的三大马车,Angular、React、Vue 只要把其中一种框架学明白,底层原理实现,其他两个学起来不会很吃力,这也取决于你以后就职的公司要求你会哪一个框架了,当然,会的越多越好,但是往往每个人的时间是有限的,对于自学的学生,或者即将面试找工作的人,当然要选择一门框架深挖原理。

以 Vue 为例,我整理了如下的面试题。

Vue部分截图

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-3ta8XeEG-1712490336188)]

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐