vlambda博客
学习文章列表

异步编程 | Js实现定时打印的几种方式

前几周学习了《》、《》、《》、《》、《》、《》。本篇来看看分别用setTimeout、Promise、async/await、Genarator来实现定时打印数组中的值的实现。


只有Es5时的实现方式

闭包+递归+setTimeout:

//闭包+递归+setTimeoutconst list = [1, 2, 3];function show() { let count = 0; return function showArr(arr) { setTimeout(() => { console.log("打印:", arr[count++]); if (count === arr.length) { return; } showArr(arr); }, 1000); };}const showArr = show();showArr(list);


有了ES6的实现方式

1、promise+async/await+for循环:

//promise+await+for循环const list = [1, 2, 3];const square = (num) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(num); }, 1000); });};
async function showArr(list) { for(let item of list) { let value = await square(item) console.log("打印:", value); }}showArr(list)

2、Generator+async/await+for...of循环

const list = [1, 2, 3];
function* square(value) { yield new Promise((rs,rj)=> { setTimeout(() => { rs(value) console.log("打印:", value); }, 1000*value); })}
function showArr(list) { for(let item of list) { let obj = square(item)      console.log('obj:', obj) let next = obj.next() //前面一个next执行完后面的next才会执行 }}showArr(list)

关于Generator实现的要点是,调用Generator的迭代器,只有通过迭代器的next方法才能执行下一个yield结果,不调用不会执行yield语句;且多个next()语句是按照其代码书写顺序执行。也就是,调用多个迭代器的next(),按书写顺序逐一调用yield语句后面的表达式。


更多:for...of会自动调用Generator函数,且按语句书写顺序逐一执行函数中的yield语句。

function* foo() { yield 1; yield 2; yield 3; yield 4; yield 5; return 6; //没有return执行效果一样}
for (let v of foo()) { console.log(v);}// 1 2 3 4 5