欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript?getter?setter金字塔???????

 更新時(shí)間:2022年08月17日 15:04:48   作者:JamesZhang80078  
這篇文章主要介紹了JavaScript?getter?setter金字塔???????,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

引言

英文鏈接: staltz.com/javascript-…

函數(shù)是JavaScript的基石。 它是一種靈活的、抽象的,可作為其他抽象的基礎(chǔ), 如:Promise、Iterables、Observables等。 之前我在會(huì)議或研討會(huì)中傳遞這些概念,隨著時(shí)間的推移,我發(fā)現(xiàn)這些抽象的概念可以抽象為金字塔狀排列的模型,在本文中,將介紹金字搭中的各層。

函數(shù)

JavaScript的基礎(chǔ)是一級值,如: numbers、strings、objects、booleans等。 雖然,您可以只使用這些值和控制流(if/else/for等)來編寫程序,但很快您可能需要編寫一個(gè)新的函數(shù)來改進(jìn)您的程序。

JavaScript中必須通過函數(shù)進(jìn)行抽象,像異步I/O操作等通常都必須使用callback回調(diào)函數(shù)。 JavaScript中的函數(shù),與【函數(shù)式編程】中的純函數(shù)不同,建議最好將它們簡單理解為“流程”,因?yàn)樗坏枚栊缘目芍赜么a塊,具有可選的輸入(參數(shù))和可選的輸出(返回值)

與硬編碼相比,函數(shù)有以下幾個(gè)重要的好處:

  • 懶惰/可重用性, 函數(shù)內(nèi)的代碼必須是惰性的(即除非被調(diào)用,否則不會(huì)執(zhí)行)才能使其可重用
  • 實(shí)現(xiàn)的靈活性,函數(shù)的使用者并不關(guān)心函數(shù)內(nèi)部是如何實(shí)現(xiàn)的,這意味著可以各種方式靈活的實(shí)現(xiàn)函數(shù)。

getters

getter是一種不用傳遞任何參數(shù)但需要有返回值的函數(shù)。
函數(shù)定義: () => X

getter是一種不用傳遞任何參數(shù)但需要有返回值的函數(shù)。 JavaScript中有許多這樣的getter, 例如: Math.random()、Date.now()等

getter作為值的抽象也很有用,例如:user 與 getUser

const user = {name: 'Alice', age:30};
console.log(user.name); // Alice
function getUser(){
	return {name: 'Alice', age:30};
}
console.log(getUser().name); // Alice

通過使用getter, 我們可以利用函數(shù)的一個(gè)好處: 惰性. 即我們不調(diào)用 getUser(),user對象就不會(huì)被白白創(chuàng)建。 同時(shí),我們利用了函數(shù)的另一好處:實(shí)現(xiàn)的靈活性, 因?yàn)槲覀兛梢酝ㄟ^多種不同的方式來返回對象。

getter還允許我們對副作用有一個(gè)鉤子,當(dāng)執(zhí)行g(shù)etter時(shí),我們可以觸發(fā)有用的副作用函數(shù),比如console.log輸出日志 或是 觸發(fā)Analytics事件等,例如:

function getUser(){
	Analytics.sendEvent('User object is now being accessed');
	return {name:'Alice', age:30};
}

getter上的計(jì)算,也是可以抽象的。例如:

function add(getX, getY){
	return function getZ(){
		const x = getX();
		const y = getY();
		return x + y;
	}
}

當(dāng)getter返回不可預(yù)測的值時(shí),這種抽象計(jì)算的好處更加明顯,例如:使用getter添加Math.random:

const getTen = () => 10;
const getTenPlusRandom = add(getTen, Math.random);

console.log(getTenPlusRandom()); // 10.948117215055046
console.log(getTenPlusRandom()); // 10.796721274448556
console.log(getTenPlusRandom()); // 10.15350303918338
console.log(getTenPlusRandom()); // 10.829703269933633

比較常見的是getter與Promise一起搭配使用,因?yàn)镻romise是不可重用的計(jì)算,因此,將Promise的構(gòu)造函數(shù)包裝在一個(gè)getter中(如我們熟知的"工廠函數(shù)"或"thunk")使其可重用。

setters

setters是有一個(gè)或多個(gè)輸入?yún)?shù),但沒有返回值的函數(shù)。
函數(shù)定義: X => ()

setters是有一個(gè)或多個(gè)輸入?yún)?shù),但沒有返回值的函數(shù)。 在JavaScript運(yùn)行時(shí)或DOM中有許多這樣的setters, 比如: console.log(x), document.write(x)等。

與getter不同,setter通常不用抽象。 因?yàn)楹瘮?shù)沒有返回值,這意味著函數(shù)僅用于發(fā)送數(shù)據(jù)或執(zhí)行JavaScript命令等。 例如, 上文中的getter getTen是數(shù)字10的抽象,我們可以將它作為值進(jìn)行傳遞,但如果將函數(shù)setTen作為值傳遞是沒有意義的,因?yàn)樗鼪]有返回值。

換句話說,setter可以是其他setter的簡單包裝器。例如:簡單包裝下setter console.log:

function fancyConsoleLog(str) {
  console.log('? ' + str + ' ?');
}

getter-getters

getter-getters是一種不需要輸入?yún)?shù)且返回一個(gè)getter的函數(shù)。
函數(shù)定義: () => (() => X)

“getter-getter”: 一種特殊類型的getter,其返回值是一個(gè)getter.

對getter的原始需求是使用getter的返回值進(jìn)行迭代。
例如,我們想顯示二次冪的數(shù)字序列,我們可以使用getter getNextPowerOfTwo()

let i = 2;
function getNextPowerOfTwo() {
  const next = i;
  i = i * 2;
  return next;
}
console.log(getNextPowerOfTwo()); // 2
console.log(getNextPowerOfTwo()); // 4
console.log(getNextPowerOfTwo()); // 8
console.log(getNextPowerOfTwo()); // 16
console.log(getNextPowerOfTwo()); // 32
console.log(getNextPowerOfTwo()); // 64
console.log(getNextPowerOfTwo()); // 128

在上面示例代碼中,變量i是全局聲明的,若我們想重新迭代序列,則必須要重置變量i, 從而泄漏了getter的實(shí)現(xiàn)細(xì)節(jié)。

若想將上述代碼變?yōu)榭芍赜们也话肿兞?,我們需要?strong>getter封裝在另一個(gè)函數(shù)中,這個(gè)包裝函數(shù)也是一個(gè)getter.

function getGetNext() {
  let i = 2;
  return function getNext() {
    const next = i;
    i = i * 2;
    return next;
  }
}

let getNext = getGetNext();
console.log(getNext()); // 2
console.log(getNext()); // 4
console.log(getNext()); // 8
getNext = getGetNext(); // ?? restart!
console.log(getNext()); // 2
console.log(getNext()); // 4
console.log(getNext()); // 8
console.log(getNext()); // 16
console.log(getNext()); // 32

可以看出,getter-getter是一種特殊類型的getter, 它繼承了getter的所有優(yōu)點(diǎn),例如:

  • 實(shí)現(xiàn)的靈活性
  • 用于副作用的鉤子(hook)
  • 惰性,其惰性體現(xiàn)在函數(shù)在初始化時(shí),外部函數(shù)啟用延遲初始化,而內(nèi)部函數(shù)啟用值時(shí)延遲初始化。
function getGetNext() {
  // ?? LAZY INITIALIZATION
  let i = 2;

  return function getNext() {
    // ?? LAZY ITERATION
    const next = i;
    i = i * 2;
    return next;
  }
}

setter-setter

setter-setter是一種以setter作為輸入且無返回值的函數(shù)。 函數(shù)定義: (X => ()) => ()

setter-setter是一種特殊的setter函數(shù),其中傳遞的參數(shù)也是setter。雖然基本的setter不是抽象函數(shù),但setter-setter是能夠表示可在代碼庫中傳遞的值的抽象。 例如下列中,通過這個(gè)setter來表示數(shù)字10:

function setSetTen(setTen) {
  setTen(10)
}

注意: setter沒有返回值。

通過簡單地重構(gòu),讓上述示例代碼的可讀性更強(qiáng):

function setTenListener(cb) {
  cb(10)
}

cb,即callback縮寫,名為“回調(diào)”,它表明在JavaScript中如何使用setter-setter。

在JavaScript中,有大量回調(diào)的案例。 顧名思義,cb代表“回調(diào)”,通過上述示例代碼來說明,cb在setter-setter如何使用。

下面兩個(gè)示例,在功能上是等價(jià)的,但是調(diào)用方式不同。

setSetTen(console.log);

// compare with...

console.log(getTen());

setter-setter具有與getter-getter相同的好處:

  • 實(shí)現(xiàn)的靈活性
  • 用于副作用的鉤子(hook)
  • 惰性,其惰性體現(xiàn)在函數(shù)在初始化時(shí),外部函數(shù)啟用延遲初始化,而內(nèi)部函數(shù)啟用值時(shí)延遲初始化。

同時(shí),它還有兩個(gè)getter-getter所沒有的新特性:

  • 控制反轉(zhuǎn)
  • 異步性

在上面的示例中,使用getter的代碼指示何時(shí)使用“console.log”使用getter。
然而,當(dāng)使用setter-setter時(shí),setter-seter本身決定何時(shí)調(diào)用“console.log”。 這種控制反轉(zhuǎn)允許setter-setter擁有比getter更大的能力,例如通過向回調(diào)函數(shù)傳遞許多值, 例如:

function setSetTen(setTen) {
  setTen(10)
  setTen(10)
  setTen(10)
  setTen(10)
}

控制反轉(zhuǎn)還可以使setter決定何時(shí)向回調(diào)傳遞值,例如: 異步傳遞。 試想一下,若將“setSetTen”的更換為“setTenListener”呢?

function setTenListener(cb) {
  setTimeout(() => { cb(10); }, 1000);
}

setter-setter在JavaScript異步編程中的很常見,但回調(diào)函數(shù)不一定是異步的。
例如,下面的“setSetTen”示例中,它是同步的:

function setSetTen(setTen) {
  setTen(10)
}

console.log('before');
setSetTen(console.log);
console.log('after');

// (Log shows:)
// before
// 10
// after

iterables

iterable是省略了實(shí)現(xiàn)細(xì)節(jié)的getter-getter, 其返回值是一個(gè)描述型的對象值或完成時(shí)的對象。

An iterable is (with some details omitted:) a getter-getter of an object that describes either a value or completion

函數(shù)定義: () => (() => ({done, value}))

getter-getter可以重啟序列值,但它沒有通知序列何時(shí)結(jié)束的約定。
Iterables是一種特殊的getter-getter,它的返回值中始終有2個(gè)屬性對象:

  • done,布爾值,表示是否完成
  • value,任意值,實(shí)際傳遞的值(在done的值不為true時(shí))

完成指示符done,能夠使iterable的代碼在執(zhí)行時(shí),知道后續(xù)GET將返回?zé)o效數(shù)據(jù),因此iterable知道何時(shí)停止迭代。
在下面的示例中,我們可以根據(jù)完成指示符生成一個(gè)偶數(shù)范圍為40到48的有限序列:

function getGetNext() {
  let i = 40;
  return function getNext() {
    if (i <= 48) {
      const next = i;
      i += 2;
      return {done: false, value: next};
    } else {
      return {done: true};
    }
  }
}

let getNext = getGetNext();
for (let result = getNext(); !result.done; result = getNext()) {
  console.log(result.value);
}

ES6 Iterables除了簡單的() => (() => ({done, value}))模式之外,還有更多的約定。它們在每個(gè)getter上添加了一個(gè)包裝器對象:

  • 外部getter包含對象:{[Symbol.iterator]:f}
  • 內(nèi)部getter包含對象: {next:g}

以下是與上一個(gè)示例代碼功能等價(jià)的ES6 Iterable代碼:

const oddNums = {
  [Symbol.iterator]: () => {
    let i = 40;
    return {
      next: () => {
        if (i <= 48) {
          const next = i;
          i += 2;
          return {done: false, value: next};
        } else {
          return {done: true};
        }
      }
    }
  }
}
let iterator = oddNums[Symbol.iterator]();
for (let result = iterator.next(); !result.done; result = iterator.next()) {
  console.log(result.value);
}

注意,兩個(gè)示例間實(shí)現(xiàn)的差異點(diǎn):

-function getGetNext() {
+const oddNums = {
+  [Symbol.iterator]: () => {
     let i = 40;
-  return function getNext() {
+    return {
+      next: () => {
         if (i <= 48) {
           const next = i;
           i += 2;
           return {done: false, value: next};
         } else {
           return {done: true};
         }
       }
+    }
   }
+}

-let getNext = getGetNext();
-for (let result = getNext(); !result.done; result = getNext()) {
+let iterator = oddNums[Symbol.iterator]();
+for (let result = iterator.next(); !result.done; result = iterator.next()) {
  console.log(result.value);
}

ES6提供了語法糖for let以便快速迭代對象:

for (let x of oddNums) {
  console.log(x);
}

為了方便創(chuàng)建Iterables,ES6還提供了生成器函數(shù)語法糖 function*

function* oddNums() {
  let i = 40;
  while (true) {
    if (i <= 48) {
      const next = i;
      i += 2;
      yield next;
    } else {
      return;
    }
  }
}

使用生產(chǎn)端語法糖和**消費(fèi)端語法糖*,自2015年以來,可迭代函數(shù)是JavaScript中可完成值序列的易于使用的抽象。請注意,調(diào)用生成器函數(shù)將返回可迭代函數(shù),生成器函數(shù)本身不是可迭代函數(shù):

自2015年后,更易于使用iterables來抽象可序列化對象值。 需要注意的是,調(diào)用生成器函數(shù)將返回一個(gè)可迭代對象,生成器函數(shù)本身不可迭代。

function* oddNums() {
  let i = 40;
  while (true) {
    if (i <= 48) {
      yield i;
      i += 2;
    } else {
      return;
    }
  }
}

for (let x of oddNums()) {
  console.log(x);
}

promises

Promise是一個(gè)(省略了一些細(xì)節(jié))特殊的setter, 它包含2個(gè)setter, 并且還有額外的保障。
函數(shù)定義: (X => (), Err => ()) => ()

雖然setter-setter功能強(qiáng)大,但由于控制反轉(zhuǎn),它們可能變得非常不可預(yù)測。

  • 它們可以是同步或異步的
  • 也可以隨時(shí)間傳遞零或一個(gè)或多個(gè)值。

Promise是一種特殊的setter,它為返回值提供一些特殊的保證:

  • 內(nèi)部setter(“回調(diào)”)從不同步調(diào)用
  • 內(nèi)部setter最多調(diào)用一次
  • 提供了一個(gè)可選的第二setter,用于傳遞錯(cuò)誤值

將下面的setter與等價(jià)的Promise代碼比較,可以看出:

  • Promise只提供一次值,且不會(huì)在兩個(gè)console.log輸出
  • Promise的返回值是異步返回的:

setter-setter的實(shí)現(xiàn):

function setSetTen(setTen) {
  setTen(10)
  setTen(10)
}

console.log('before setSetTen');
setSetTen(console.log);
console.log('after setSetTen');

// (Log shows:)
// before setSetTen
// 10
// 10
// after setSetTen

promise的實(shí)現(xiàn):

const tenPromise = new Promise(function setSetTen(setTen) {
  setTen(10);
  setTen(10);
});

console.log('before Promise.then');
tenPromise.then(console.log);
console.log('after Promise.then');

// (Log shows:)
// before Promise.then
// after Promise.then
// 10

Promise可以方便的用于表示:一個(gè)異步且只返回一次的值。 在ES2017以后,可以使用async - await語法糖來編寫Promise。 在函數(shù)前使用async關(guān)鍵字,在需要使用Promise值的位置使用await來接收值。

async function main() {
  console.log('before await');
  const ten = await new Promise(function setSetTen(setTen) {
    setTen(10);
  });
  console.log(ten);
  console.log('after await');
}

main();

// (Log shows:)
// before await
// 10
// after await

語法糖async - await也可用于創(chuàng)建Promise, 因?yàn)?code>async函數(shù)將返回一個(gè)Promise對象,該P(yáng)romise對象將返回return的值。

async function getTenPromise() {
  return 10;
}
const tenPromise = getTenPromise();

console.log('before Promise.then');
tenPromise.then(console.log);
console.log('after Promise.then');

// (Log shows:)
// before Promise.then
// after Promise.then
// 10

Observables

observable是(省略了一些細(xì)節(jié):)一個(gè)包含有3個(gè)setter的setter函數(shù),并帶有額外的保障。
函數(shù)定義: (X => (), Err => (), () => ()) => ()

GetterSetterFunctionValue

像Iterables一樣,GetterSetterFunctionValue是一種特殊類型的getter-getter,它增加了發(fā)送完成信號的能力,Observable也是一種setter-setter,它也增加了完成能力。
JavaScript中的典型setter-setter,如: element.addEventListener不會(huì)通知事件流是否完成,因此很難連接事件流或執(zhí)行其他與完成相關(guān)的邏輯。

與JavaScript規(guī)范中標(biāo)準(zhǔn)化的可伸縮性不同,可觀測性是在幾個(gè)庫中找到的松散約定,如:

  • RxJS
  • most.js
  • xstream
  • Bacon.js

盡管正在考慮將proposal-observable作為一個(gè)TC39方案,但該方案仍在不斷修改。
因此在本文中,讓我們假設(shè)遵循Fantasy Observable規(guī)范(其中RxJS、most.js和xstream等最受歡迎庫都遵循這一規(guī)范)。

Observables the dual of Iterables,有以下特性:

可迭代:

  • 它是一個(gè)對象
  • 可迭代,有一個(gè)“iterate”屬性方法,即:Symbol.iterator
  • “iterate” 方法是迭代器對象的 getter 
  • 迭代器對象有一個(gè)名為next的 getter

可觀察:

  • 它是一個(gè)對象
  • 有可觀察method,即:subscribe
  • 可觀察method是Observer對象的setter
  • Observer有一個(gè)名為nextsetter

Observer對象還可以包含另外兩個(gè)方法:

  • complete,表示成功完成,相當(dāng)于iterator中的“done”指示符
  • error,表示失敗完成,相當(dāng)iterator中執(zhí)行時(shí)引發(fā)異常

與Promise一樣,Observable為返回值增加了一些保障:

  • 一旦調(diào)用了complete,則不會(huì)調(diào)用error
  • 一旦調(diào)用了error,就不會(huì)調(diào)用complete
  • 一旦調(diào)用了complete或error,則不會(huì)調(diào)用next

在下面的示例中,Observable用于異步返回有限的數(shù)字序列

const oddNums = {
  subscribe: (observer) => {
    let x = 40;
    let clock = setInterval(() => {
      if (x <= 48) {
        observer.next(x);
        x += 2;
      } else {
        observer.complete();
        clearInterval(clock);
      }
    }, 1000);
  }
};

oddNums.subscribe({
  next: x => console.log(x),
  complete: () => console.log('done'),
});

// (Log shows:)
// 40
// 42
// 44
// 46
// 48
// done

與setter-setter一樣,Observable具有控制反轉(zhuǎn)的能力,因此消費(fèi)端(oddNums.subscribe)無法暫?;蛉∠麄魅氲臄?shù)據(jù)流。
大多數(shù)Observable的實(shí)現(xiàn)都添加了一個(gè)重要的細(xì)節(jié),允許消費(fèi)者取消訂閱: unsubscribe。

“subscribe”函數(shù)將返回一個(gè)對象subscription,即“unsubscribe”。 消費(fèi)端可以使用該方法取消訂閱。
因此,“subscribe”不再是setter,因?yàn)樗且粋€(gè)具有輸入(觀察者)和輸出(訂閱)的函數(shù)。

下面,我們在前面的示例中添加了一個(gè)訂閱對象:

const oddNums = {
  subscribe: (observer) => {
    let x = 40;
    let clock = setInterval(() => {
      if (x <= 48) {
        observer.next(x);
        x += 2;
      } else {
        observer.complete();
        clearInterval(clock);
      }
    }, 1000);
    // ?? Subscription:
    return {
      unsubscribe: () => {
        clearInterval(clock);
      }
    };
  }
};

const subscription = oddNums.subscribe({
  next: x => console.log(x),
  complete: () => console.log('done'),
});

// ?? Cancel the incoming flow of data after 2.5 seconds
setTimeout(() => {
  subscription.unsubscribe();
}, 2500);

// (Log shows:)
// 40
// 42

async iterables

異步可迭代函數(shù)(省略了一些細(xì)節(jié))類似于yield promise的可迭代函數(shù)
函數(shù)定義: () => (() => Promise<{done, value}>)

Iterables可以表示任何無限或有限的值序列,但它們有一個(gè)限制:

  • 只要使用者調(diào)用next()方法,返回值就必須是同步的。

AsyncIterables擴(kuò)展了Iterables的功能,它通過允許延后返回值,而不是在調(diào)用時(shí)立即返回。
AsyncIterables通過使用Promise實(shí)現(xiàn)值的異步傳遞,因?yàn)镻romise表示單個(gè)異步值。每次調(diào)用迭代器的next()(內(nèi)部getter函數(shù)),都會(huì)創(chuàng)建并返回一個(gè)Promise。 在下面的示例中,我們以oddNums可迭代為例,其在迭代時(shí)每次返回一個(gè)Promise對象:

function slowResolve(val) {
  return new Promise(resolve => {
    setTimeout(() => resolve(val), 1000);
  });
}

function* oddNums() {
  let i = 40;
  while (true) {
    if (i <= 48) {
      yield slowResolve(i); // ?? yield a Promise
      i += 2;
    } else {
      return;
    }
  }
}

要使用Asynciteable,我們可以使用async - await語法糖,來遍歷&獲取異步迭代器的值:

async function main() {
  for (let promise of oddNums()) {
    const x = await promise;
    console.log(x);
  }
  console.log('done');
}
main();
// (Log shows:)
// 40
// 42
// 44
// 46
// 48
// done

雖然上例中通過async - await語法糖(ES6語法)能夠編寫出可讀性較好的代碼。但是,在ES2018中,異步迭代是通過{done,value}(Promise)對象來迭代的。

比較一下ES6&ES2018異步迭代器的函數(shù)定義:

  • ES6異步迭代器: () => (() => {done, value: Promise<X>})
  • ES2018異步迭代器: () => (() => Promise<{done, value}>)

可以看出,ES2018異步可迭代函數(shù)返回的不是一個(gè)可迭代函數(shù),它將返回一個(gè)Promise對象,但在許多方面與ES6異步迭代器相似。
這一細(xì)節(jié)的原因是,異步可伸縮性還需要允許異步發(fā)送完成(done),因此Promise必須包裹{done,value}對象。

因?yàn)锳syncIterables不是Iterables,所以它們使用不同的符號。

  • Iterables 使用Symbol.iterator
  • AsyncIterables 使用'Symbol.asyncItrator'

在下面的示例中,我們使用ES2018 AsyncIterable實(shí)現(xiàn)了一個(gè)前例等價(jià)的功能:

const oddNums = {
  [Symbol.asyncIterator]: () => {
    let i = 40;
    return {
      next: () => {
        if (i <= 48) {
          const next = i;
          i += 2;
          return slowResolve({done: false, value: next});
        } else {
          return slowResolve({done: true});
        }
      }
    };
  }
};

async function main() {
  let iter = oddNums[Symbol.asyncIterator]();
  let done = false;
  for (let promise = iter.next(); !done; promise = iter.next()) {
    const result = await promise;
    done = result.done;
    if (!done) console.log(result.value);
  }
  console.log('done');
}
main();

像Iterables有語法糖function*for–let–of,以及Promises有async–await語法糖一樣,ES2018中的AsyncIterable有兩個(gè)語法糖功能:

  • 生產(chǎn)端:async function*
  • 消費(fèi)端:for–await–let–of

在下面的示例中,我們使用這兩種功能創(chuàng)建異步數(shù)字序列,并使用for-await循環(huán)遍歷它們:

function sleep(period) {
  return new Promise(resolve => {
    setTimeout(() => resolve(true), period);
  });
}

// ?? Production side can use both `await` and `yield`
async function* oddNums() {
  let i = 40;
  while (true) {
    if (i <= 48) {
      await sleep(1000);
      yield i;
      i += 2;
    } else {
      await sleep(1000);
      return;
    }
  }
}

async function main() {
  // ?? Consumption side uses the new syntax `for await`
  for await (let x of oddNums()) {
    console.log(x);
  }
  console.log('done');
}

main();

盡管它們是新特性,但Babel、TypeScript、Firefox、Chrome、Safari 和 Node.js中都已經(jīng)支持了。

AsyncIterables可以方便地結(jié)合基于Promise的API(如fetch)來創(chuàng)建異步序列。 例如在數(shù)據(jù)庫中列出用戶,每次請求一個(gè)用戶:

async function* users(from, to) {
  for (let x = from; x <= to; x++) {
    const res = await fetch('http://jsonplaceholder.typicode.com/users/' + x);
    const json = await res.json();
    yield json;
  }
}

async function main() {
  for await (let x of users(1, 10)) {
    console.log(x);
  }
}

main();

operators

在本文中,抽象的列舉了一些特殊的JavaScript函數(shù)示例。 根據(jù)定義,它們的功能的不可能比函數(shù)更強(qiáng)大。因此,函數(shù)是最強(qiáng)大、最靈活的抽象。完全靈活性的缺點(diǎn)是不可預(yù)測性,這些抽象提供的是“保證”,基于這些“保證”,讓您可以編寫更有組件、更可預(yù)測的代碼。

另一方向, 函數(shù)可以作為JavaScript的值,允許將它進(jìn)行傳遞和操縱。
在本文中,我們將Iterable、Observable、AsyncIterable作為值進(jìn)行傳遞,并在傳遞過程中對其進(jìn)行操作。

最常見的操作之一是map映射,它在數(shù)組中經(jīng)常使用到,但也與其他抽象相關(guān)。 在下面的示例中,我們?yōu)锳syncIterables創(chuàng)建map操作符,并使用它用來創(chuàng)建異步迭代器,以獲取數(shù)據(jù)庫的用戶信息。

async function* users(from, to) {
  for (let i = from; i <= to; i++) {
    const res = await fetch('http://jsonplaceholder.typicode.com/users/' + i);
    const json = await res.json();
    yield json;
  }
}

// ?? Map operator for AsyncIterables
async function* map(inputAsyncIter, f) {
  for await (let x of inputAsyncIter) {
    yield f(x);
  }
}

async function main() {
  const allUsers = users(1, 10);
  // ?? Pass `allUsers` around, create a new AsyncIterable `names`
  const names = map(allUsers, user => user.name);
  for await (let name of names) {
    console.log(name);
  }
}

main();

上面的示例代碼,沒有被抽象至Getter - Setter金字塔中。
若使用getter - setter來實(shí)現(xiàn),需要更多的代碼,可讀性也不好。
因此,在不犧牲可讀性的情況下,使用運(yùn)算符和新的語法糖,用更少的代碼編寫函數(shù)做更多的事情,以處理這種特殊的場景。

到此這篇關(guān)于JavaScript getter setter金字塔的文章就介紹到這了,更多相關(guān)JavaScript getter-setter金字塔內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • javascript結(jié)合CSS實(shí)現(xiàn)蘋果開關(guān)按鈕特效

    javascript結(jié)合CSS實(shí)現(xiàn)蘋果開關(guān)按鈕特效

    這篇文章主要介紹了javascript結(jié)合CSS實(shí)現(xiàn)蘋果開關(guān)按鈕特效的方法以及全部代碼,效果非常不錯(cuò),兼容性也很好,有需要的小伙伴自己參考下
    2015-04-04
  • JS中setTimeout和setInterval的最大延時(shí)值詳解

    JS中setTimeout和setInterval的最大延時(shí)值詳解

    這篇文章主要介紹了JS中setTimeout和setInterval的最大延時(shí)值的相關(guān)資料,文中通過示例代碼介紹的很詳細(xì),相信對大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-02-02
  • Bmail聯(lián)系人飛來飛去效果

    Bmail聯(lián)系人飛來飛去效果

    Bmail聯(lián)系人飛來飛去效果...
    2007-01-01
  • js中el表達(dá)式的使用和非空判斷方法

    js中el表達(dá)式的使用和非空判斷方法

    下面小編就為大家分享一篇js中el表達(dá)式的使用和非空判斷方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • 詳解JS中的快速排序與冒泡

    詳解JS中的快速排序與冒泡

    本文主要介紹了快速排序思想與冒泡排序思想。具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • JS獲取元素多層嵌套思路詳解

    JS獲取元素多層嵌套思路詳解

    這篇文章主要介紹了JS獲取元素多層嵌套思路詳解的相關(guān)資料,需要的朋友可以參考下
    2016-05-05
  • json對象和formData相互轉(zhuǎn)換的方式詳解

    json對象和formData相互轉(zhuǎn)換的方式詳解

    我們有兩種常見的傳參方式: JSON 對象格式和 formData 格式,但是一些場景是需要我們對這兩種數(shù)據(jù)格式進(jìn)行轉(zhuǎn)換的,這篇文章主要介紹了json對象和formData相互轉(zhuǎn)換的方式詳解,需要的朋友可以參考下
    2023-02-02
  • JavaScript圖片上傳并預(yù)覽的完整實(shí)例

    JavaScript圖片上傳并預(yù)覽的完整實(shí)例

    上傳是個(gè)老生常談的話題了,多數(shù)情況下各位想必用的是uplodify,webUploader之類的插件,這篇文章主要給大家介紹了關(guān)于JavaScript圖片上傳并預(yù)覽的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • 微信小程序收貨地址API兼容低版本解決方法

    微信小程序收貨地址API兼容低版本解決方法

    這篇文章主要介紹了微信小程序收貨地址API兼容低版本解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 用js模擬struts2的多action調(diào)用示例

    用js模擬struts2的多action調(diào)用示例

    這篇文章主要介紹了用js模擬struts2的多action調(diào)用的實(shí)現(xiàn)過程,需要的朋友可以參考下
    2014-05-05

最新評論