iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 28
0
自我挑戰組

利用30分鐘~想一個前端問題系列 第 28

利用30分鐘~想一個前端問題 Day28-chainAsync

chainAsync

Chains asynchronous functions.

Loop through an array of functions containing asynchronous events, calling next when each asynchronous event has completed.

循環遍歷包含異步事件的函數陣列,每次異步事件完成後調用 next。

const chainAsync = fns => {
  let curr = 0;
  const last = fns[fns.length - 1];
  const next = () => {
    const fn = fns[curr++];
    fn === last ? fn() : fn(next);
  };
  next();
};
//EXAMPLES
chainAsync([
  next => {
    console.log('0 seconds');
    setTimeout(next, 1000);
  },
  next => {
    console.log('1 second');
    setTimeout(next, 1000);
  },
  () => {
    console.log('2 second');
  }
]);

分析點

  1. ES6 Iterables/Iterators 迭代器

什麼東西符合 Iterator 的定義

  • 定義一個物件將如何被遍歷
  • 讓資料結構中的成員,可以按照你控制的順序來做排列

像是 Array, Object, Map, Set,好像都有符合上列的條件,es6為此統整一個統一的機制叫做 iterator。

在 JavaScript 中,一個 Iterator 只是一個有提供 next() 方法的物件。

next() 方法:

{ value: undefined, done: true }

其中value表示此次遍歷的結果,done表示是否已經遍歷完畢。

每一次 next() 被調用時,會返回一個有 done 和 value 屬性的物件 ,done 是一個 boolean,如果是 true 表示遍歷結束,value 則是當前遍歷到的成員的值,可以把它想像成一個指針,跑到第一個位置時,更新資料結構的第一個地方,第二次調用 next() 時,則返回第二個成員,同時更新 第二個地方,再一次調用 next() 時,返回 {done: true} 表示結束。

function each(data){
  //生成遍歷器
  let Iterator =  data[Symbol.iterator]()
  console.log(iterator.next())
   console.log(iterator.next())
    console.log(iterator.next())
     console.log(iterator.next())
       console.log(iterator.next())
     console.log(iterator.next())
}

let arr = [1,2,3,4]
let node = document.getElementsByTagName('p');
let m = new Map();
m.set('a',100)
m.set('b',100)

1.each(arr) console.log 出現的結果為

對吧,因為陣列只到4,但因為遍歷沒有結束所以done:false

2.each(node)

3.m.set('a',100)& m.set('b',100)

Map和 Set 是可以迭代的,物件是用鍵值(key)來儲存資料的無順序的集合,且資料可以是不同的資料型。

可迭代的資料型別有 string、array、array-like object、map 和 set,這是因為它們已內建 @@iterator 方法,意即定義 Symbol.iterator 屬性的值為一個符合迭代器協議的函式。

參考文章

Iterator 和 for...of 循环
iterable


上一篇
利用30分鐘~想一個前端問題 Day27-httpGet
下一篇
利用30分鐘~想一個前端問題 Day29-matches
系列文
利用30分鐘~想一個前端問題30

尚未有邦友留言

立即登入留言