ECMAScript6(16):异步编程,搞懂这些直接来阿里入职

  • 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){

step(function(){ return gen.next(data); });

}, function(e){

step(function(){ return gen.throw(e); });

});

}

step(function() { return gen.next(undefined); });

});

}

}

我们使用 async 函数做点简单的事情:

function timeout(ms){

return new Promise((resolve) => {

setTimeout(resolve, ms);

});

}

async function delay(nap, …values){

while(1){

try{

await timeout(nap);

} catch(e) {

console.log(e);

}

var val = values.shift();

if(val)

console.log(val)

else

break;

}

}

delay(600,1,2,3,4); //每隔 600ms 输出一个数

这里需要注意:应该把后面跟 promise对象的 await 放在一个 try 中,防止其被 rejected。当然上面的 try 语句也可以这样写:

var ms = await timeout(nap).catch((e) => console.log(e));

对于函数参数中的回调函数不建议使用,避免出现不应该的错误

//反例: 会得到错误结果

async function fun(db){

let docs = [{},{},{}];

docs.forEach(async function(doc){ //ReferenceError: Invalid left-hand side in assignment

await db.post(doc);

});

}

//改写, 但依然顺序执行

async function fun(db){

let docs = [{},{},{}];

for(let doc of docs){

await db.post(doc);

}

}

//改写, 并发执行

async function fun(db){

let docs = [{},{},{}];

let promises = docs.map((doc) => db.post(doc));

let result = await Promise.all(promises)

console.log(result);

}

//改写, 并发执行

async function fun(db){

let docs = [{},{},{}];

let promises = docs.map((doc) => db.post(doc));

let result = [];

for(let promise of promises){

result.push(await promise);

}

console.log(result);

}

Promise,Generator 和 async 函数比较

这里我们实现一个简单的功能,可以直观的比较一下。实现如下功能:

在一个 DOM 元素上绑定一系列动画,每一个动画完成才开始下一个,如果某个动画执行失败,返回最后一个执行成功的动画的返回值

  • Promise 方法

function chainAnimationPromise(ele, animations){

var ret = null; //存放上一个动画的返回值

var p = Promise.resolve();

for(let anim of animations){

p = p.then(function(val){

ret = val;

return anim(ele);

});

}

return p.catch(function(e){

/忽略错误/

}).then(function(){

return ret; //返回最后一个执行成功的动画的返回值

});

}

  • Generator 方法

function chainAnimationGenerator(ele, animations){

return fun(function*(){

var ret = null;

try{

for(let anim of animations){

ret = yield anim(ele);

}

} catch(e) {

/忽略错误/

}

return ret;

});

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){

step(function(){ return gen.next(data); });

}, function(e){

step(function(){ return gen.throw(e); });

});

}

step(function() { return gen.next(undefined); });

});

}

}

  • async 函数方法

async function chainAnimationAsync(ele, animations){

var ret = null;

try{

for(let anim of animations){

ret = await anim(elem);

}

} catch(e){

/忽略错误/

}

return ret;

}

一个经典题

console.log(0);

setTimeout(function(){

console.log(1)

},0);

setTimeout(function(){

console.log(2);

},1000);

var pro = new Promise(function(resolve, reject){

console.log(3);

resolve();

}).then(resolve => console.log(4));

console.log(5);

setTimeout(function(){

console.log(6)

},0);

pro.then(resolve => console.log(7));

var pro2 = new Promise(function(resolve, reject){

console.log(8);

resolve(10);

}).then(resolve => console.log(11))

.then(resolve => console.log(12))

.then(resolve => console.log(13));

console.log(14);
// 0 3 5 8 14 4 11 7 12 13 1 6 2

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

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

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

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

css

1,盒模型
2,如何实现一个最大的正方形
3,一行水平居中,多行居左
4,水平垂直居中
5,两栏布局,左边固定,右边自适应,左右不重叠
6,如何实现左右等高布局
7,画三角形
8,link @import导入css
9,BFC理解

js

1,判断 js 类型的方式
2,ES5 和 ES6 分别几种方式声明变量
3,闭包的概念?优缺点?
4,浅拷贝和深拷贝
5,数组去重的方法
6,DOM 事件有哪些阶段?谈谈对事件代理的理解
7,js 执行机制、事件循环
8,介绍下 promise.all
9,async 和 await,
10,ES6 的 class 和构造函数的区别
11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式,
12,介绍一下rAF(requestAnimationFrame)
13,javascript 的垃圾回收机制讲一下,
14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?

垂直居中
5,两栏布局,左边固定,右边自适应,左右不重叠
6,如何实现左右等高布局
7,画三角形
8,link @import导入css
9,BFC理解

[外链图片转存中…(img-w11EMrvQ-1710592693645)]

js

1,判断 js 类型的方式
2,ES5 和 ES6 分别几种方式声明变量
3,闭包的概念?优缺点?
4,浅拷贝和深拷贝
5,数组去重的方法
6,DOM 事件有哪些阶段?谈谈对事件代理的理解
7,js 执行机制、事件循环
8,介绍下 promise.all
9,async 和 await,
10,ES6 的 class 和构造函数的区别
11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式,
12,介绍一下rAF(requestAnimationFrame)
13,javascript 的垃圾回收机制讲一下,
14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?

[外链图片转存中…(img-c1t8zKzU-1710592693645)]

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值