国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

你是怎么理解ES6中 Generator的?使用場景?

這篇具有很好參考價(jià)值的文章主要介紹了你是怎么理解ES6中 Generator的?使用場景?。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

這里給大家分享我在網(wǎng)上總結(jié)出來的一些知識(shí),希望對大家有所幫助

你是怎么理解ES6中 Generator的?使用場景?

一、介紹

Generator 函數(shù)是 ES6 提供的一種異步編程解決方案,語法行為與傳統(tǒng)函數(shù)完全不同

回顧下上文提到的解決異步的手段:

  • 回調(diào)函數(shù)
  • promise

那么,上文我們提到promsie已經(jīng)是一種比較流行的解決異步方案,那么為什么還出現(xiàn)Generator?甚至async/await呢?

該問題我們留在后面再進(jìn)行分析,下面先認(rèn)識(shí)下Generator

Generator函數(shù)

執(zhí)行?Generator?函數(shù)會(huì)返回一個(gè)遍歷器對象,可以依次遍歷?Generator?函數(shù)內(nèi)部的每一個(gè)狀態(tài)

形式上,Generator函數(shù)是一個(gè)普通函數(shù),但是有兩個(gè)特征:

  • function關(guān)鍵字與函數(shù)名之間有一個(gè)星號
  • 函數(shù)體內(nèi)部使用yield表達(dá)式,定義不同的內(nèi)部狀態(tài)
function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

二、使用

Generator?函數(shù)會(huì)返回一個(gè)遍歷器對象,即具有Symbol.iterator屬性,并且返回給自己

function* gen(){
  // some code
}

var g = gen();

g[Symbol.iterator]() === g
// true

通過yield關(guān)鍵字可以暫停generator函數(shù)返回的遍歷器對象的狀態(tài)

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}
var hw = helloWorldGenerator();

上述存在三個(gè)狀態(tài):helloworld、return

通過next方法才會(huì)遍歷到下一個(gè)內(nèi)部狀態(tài),其運(yùn)行邏輯如下:

  • 遇到yield表達(dá)式,就暫停執(zhí)行后面的操作,并將緊跟在yield后面的那個(gè)表達(dá)式的值,作為返回的對象的value屬性值。
  • 下一次調(diào)用next方法時(shí),再繼續(xù)往下執(zhí)行,直到遇到下一個(gè)yield表達(dá)式
  • 如果沒有再遇到新的yield表達(dá)式,就一直運(yùn)行到函數(shù)結(jié)束,直到return語句為止,并將return語句后面的表達(dá)式的值,作為返回的對象的value屬性值。
  • 如果該函數(shù)沒有return語句,則返回的對象的value屬性值為undefined
hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

done用來判斷是否存在下個(gè)狀態(tài),value對應(yīng)狀態(tài)值

yield表達(dá)式本身沒有返回值,或者說總是返回undefined

通過調(diào)用next方法可以帶一個(gè)參數(shù),該參數(shù)就會(huì)被當(dāng)作上一個(gè)yield表達(dá)式的返回值

function* foo(x) {
  var y = 2 * (yield (x + 1));
  var z = yield (y / 3);
  return (x + y + z);
}

var a = foo(5);
a.next() // Object{value:6, done:false}
a.next() // Object{value:NaN, done:false}
a.next() // Object{value:NaN, done:true}

var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }

正因?yàn)?code>Generator函數(shù)返回Iterator對象,因此我們還可以通過for...of進(jìn)行遍歷

function* foo() {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
  yield 5;
  return 6;
}

for (let v of foo()) {
  console.log(v);
}
// 1 2 3 4 5

原生對象沒有遍歷接口,通過Generator函數(shù)為它加上這個(gè)接口,就能使用for...of進(jìn)行遍歷了

function* objectEntries(obj) {
  let propKeys = Reflect.ownKeys(obj);

  for (let propKey of propKeys) {
    yield [propKey, obj[propKey]];
  }
}

let jane = { first: 'Jane', last: 'Doe' };

for (let [key, value] of objectEntries(jane)) {
  console.log(`${key}: ${value}`);
}
// first: Jane
// last: Doe

三、異步解決方案

回顧之前展開異步解決的方案:

  • 回調(diào)函數(shù)
  • Promise 對象
  • generator 函數(shù)
  • async/await

這里通過文件讀取案例,將幾種解決異步的方案進(jìn)行一個(gè)比較:

回調(diào)函數(shù)

所謂回調(diào)函數(shù),就是把任務(wù)的第二段單獨(dú)寫在一個(gè)函數(shù)里面,等到重新執(zhí)行這個(gè)任務(wù)的時(shí)候,再調(diào)用這個(gè)函數(shù)

fs.readFile('/etc/fstab', function (err, data) {
  if (err) throw err;
  console.log(data);
  fs.readFile('/etc/shells', function (err, data) {
    if (err) throw err;
    console.log(data);
  });
});

readFile函數(shù)的第三個(gè)參數(shù),就是回調(diào)函數(shù),等到操作系統(tǒng)返回了/etc/passwd這個(gè)文件以后,回調(diào)函數(shù)才會(huì)執(zhí)行

Promise

Promise就是為了解決回調(diào)地獄而產(chǎn)生的,將回調(diào)函數(shù)的嵌套,改成鏈?zhǔn)秸{(diào)用

const fs = require('fs');

const readFile = function (fileName) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data);
    });
  });
};


readFile('/etc/fstab').then(data =>{
    console.log(data)
    return readFile('/etc/shells')
}).then(data => {
    console.log(data)
})

這種鏈?zhǔn)讲僮餍问剑巩惒饺蝿?wù)的兩段執(zhí)行更清楚了,但是也存在了很明顯的問題,代碼變得冗雜了,語義化并不強(qiáng)

generator

yield表達(dá)式可以暫停函數(shù)執(zhí)行,next方法用于恢復(fù)函數(shù)執(zhí)行,這使得Generator函數(shù)非常適合將異步任務(wù)同步化

const gen = function* () {
  const f1 = yield readFile('/etc/fstab');
  const f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

async/await

將上面Generator函數(shù)改成async/await形式,更為簡潔,語義化更強(qiáng)了

const asyncReadFile = async function () {
  const f1 = await readFile('/etc/fstab');
  const f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

區(qū)別:

通過上述代碼進(jìn)行分析,將promiseGenerator、async/await進(jìn)行比較:

  • promiseasync/await是專門用于處理異步操作的

  • Generator并不是為異步而設(shè)計(jì)出來的,它還有其他功能(對象迭代、控制輸出、部署Interator接口...)

  • promise編寫代碼相比Generatorasync更為復(fù)雜化,且可讀性也稍差

  • Generator、async需要與promise對象搭配處理異步情況

  • async實(shí)質(zhì)是Generator的語法糖,相當(dāng)于會(huì)自動(dòng)執(zhí)行Generator函數(shù)

  • async使用上更為簡潔,將異步代碼以同步的形式進(jìn)行編寫,是處理異步編程的最終方案

四、使用場景

Generator是異步解決的一種方案,最大特點(diǎn)則是將異步操作同步化表達(dá)出來

function* loadUI() {
  showLoadingScreen();
  yield loadUIDataAsynchronously();
  hideLoadingScreen();
}
var loader = loadUI();
// 加載UI
loader.next()

// 卸載UI
loader.next()

包括redux-saga中間件也充分利用了Generator特性

import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'

function* fetchUser(action) {
   try {
      const user = yield call(Api.fetchUser, action.payload.userId);
      yield put({type: "USER_FETCH_SUCCEEDED", user: user});
   } catch (e) {
      yield put({type: "USER_FETCH_FAILED", message: e.message});
   }
}

function* mySaga() {
  yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}

function* mySaga() {
  yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}

export default mySaga;

還能利用Generator函數(shù),在對象上實(shí)現(xiàn)Iterator接口文章來源地址http://www.zghlxwxcb.cn/news/detail-839872.html

function* iterEntries(obj) {
  let keys = Object.keys(obj);
  for (let i=0; i < keys.length; i++) {
    let key = keys[i];
    yield [key, obj[key]];
  }
}

let myObj = { foo: 3, bar: 7 };

for (let [key, value] of iterEntries(myObj)) {
  console.log(key, value);
}

// foo 3
// bar 7

參考文獻(xiàn)

  • https://es6.ruanyifeng.com/#docs/generator-async

到了這里,關(guān)于你是怎么理解ES6中 Generator的?使用場景?的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 你是怎么理解ES6中Proxy的?使用場景?

    你是怎么理解ES6中Proxy的?使用場景?

    定義:?用于定義基本操作的自定義行為 本質(zhì):?修改的是程序默認(rèn)形為,就形同于在編程語言層面上做修改,屬于元編程 (meta programming) 元編程(Metaprogramming,又譯超編程,是指某類計(jì)算機(jī)程序的編寫,這類計(jì)算機(jī)程序編寫或者操縱其它程序(或者自身)作為它們的數(shù)據(jù),或

    2024年03月13日
    瀏覽(22)
  • ES6基礎(chǔ)知識(shí)六:你是怎么理解ES6中 Promise的?使用場景?

    ES6基礎(chǔ)知識(shí)六:你是怎么理解ES6中 Promise的?使用場景?

    一、介紹 Promise,譯為承諾,是異步編程的一種解決方案,比傳統(tǒng)的解決方案(回調(diào)函數(shù))更加合理和更加強(qiáng)大 在以往我們?nèi)绻幚矶鄬赢惒讲僮?,我們往往?huì)像下面那樣編寫我們的代碼 閱讀上面代碼,是不是很難受,上述形成了經(jīng)典的回調(diào)地獄 現(xiàn)在通過Promise的改寫上面的

    2024年02月15日
    瀏覽(22)
  • ES6基礎(chǔ)知識(shí)八:你是怎么理解ES6中Proxy的?使用場景?

    ES6基礎(chǔ)知識(shí)八:你是怎么理解ES6中Proxy的?使用場景?

    一、介紹 定義: 用于定義基本操作的自定義行為 本質(zhì): 修改的是程序默認(rèn)形為,就形同于在編程語言層面上做修改,屬于元編程(meta programming) 元編程(Metaprogramming,又譯超編程,是指某類計(jì)算機(jī)程序的編寫,這類計(jì)算機(jī)程序編寫或者操縱其它程序(或者自身)作為它們的

    2024年02月15日
    瀏覽(28)
  • ES6基礎(chǔ)知識(shí)五:你是怎么理解ES6新增Set、Map兩種數(shù)據(jù)結(jié)構(gòu)的?

    ES6基礎(chǔ)知識(shí)五:你是怎么理解ES6新增Set、Map兩種數(shù)據(jù)結(jié)構(gòu)的?

    如果要用一句來描述,我們可以說 Set是一種叫做集合的數(shù)據(jù)結(jié)構(gòu),Map是一種叫做字典的數(shù)據(jù)結(jié)構(gòu) 什么是集合?什么又是字典? 集合 是由一堆無序的、相關(guān)聯(lián)的,且不重復(fù)的內(nèi)存結(jié)構(gòu)【數(shù)學(xué)中稱為元素】組成的組合 字典 是一些元素的集合。每個(gè)元素有一個(gè)稱作key 的域,不同

    2024年02月16日
    瀏覽(19)
  • 【ES6】Generator 函數(shù)

    Generator 函數(shù)是 ES6 引入的一種新的函數(shù)類型,它既可以生成一個(gè)序列,又可以在某個(gè)條件下停止執(zhí)行,并在需要時(shí)恢復(fù)執(zhí)行。Generator 函數(shù)非常適合處理那些需要按需計(jì)算的場景,例如處理大數(shù)據(jù)、生成隨機(jī)數(shù)等。 Generator 函數(shù)的基本語法 Generator 函數(shù)的語法如下: 其中,* 是

    2024年02月10日
    瀏覽(21)
  • 【es6】中的Generator

    【es6】中的Generator

    Generator 函數(shù)是 ES6 提供的一種異步編程解決方案,最大特點(diǎn)交出函數(shù)的執(zhí)行權(quán)。 和普通函數(shù)不一樣的是必須調(diào)用next()才會(huì)執(zhí)行函數(shù)。 function與函數(shù)名之間有個(gè)(*)號; 不同于普通函數(shù),可暫停執(zhí)行,所以加 * 區(qū)別。 Generator 函數(shù)體內(nèi)部使用yield語句,可以定義不同的內(nèi)部狀態(tài)

    2024年02月12日
    瀏覽(15)
  • JS 怎么理解ES6新增Set、Map兩種數(shù)據(jù)結(jié)構(gòu)?

    JS 怎么理解ES6新增Set、Map兩種數(shù)據(jù)結(jié)構(gòu)?

    目錄 一、前言 二、Set 1.Set數(shù)據(jù)結(jié)構(gòu)定義 2.Set數(shù)據(jù)結(jié)構(gòu)的特性 3.Set數(shù)據(jù)結(jié)構(gòu)的基本使用 4.Set遍歷數(shù)據(jù) 5.Set 的使用場景 6.WeakSet的使用 7.垃圾回收機(jī)制 三、Map 1.Map數(shù)據(jù)結(jié)構(gòu)定義 2.Map數(shù)據(jù)結(jié)構(gòu)的特性 3.Map數(shù)據(jù)結(jié)構(gòu)的基本使用 ?4.Map遍歷數(shù)據(jù) 5.Map的使用場景 6.WeakMap的使用 7.垃圾回收

    2024年02月08日
    瀏覽(27)
  • ES6 reduce方法:示例與詳解、應(yīng)用場景

    ES6 reduce方法:示例與詳解、應(yīng)用場景

    還是大劍師蘭特 :曾是美國某知名大學(xué)計(jì)算機(jī)專業(yè)研究生,現(xiàn)為航空航海領(lǐng)域高級前端工程師;CSDN知名博主,GIS領(lǐng)域優(yōu)質(zhì)創(chuàng)作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技術(shù)開發(fā),歡迎加底部微信(gis-dajianshi),一起交流。 No. 內(nèi)容鏈接 1 Openlayers 【入門教

    2024年04月13日
    瀏覽(24)
  • 深入理解 ES6 的解構(gòu)表達(dá)式

    深入理解 ES6 的解構(gòu)表達(dá)式

    還是大劍師蘭特 :曾是美國某知名大學(xué)計(jì)算機(jī)專業(yè)研究生,現(xiàn)為航空航海領(lǐng)域高級前端工程師;CSDN知名博主,GIS領(lǐng)域優(yōu)質(zhì)創(chuàng)作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技術(shù)開發(fā),歡迎加底部微信(gis-dajianshi),一起交流。 No. 內(nèi)容鏈接 1 Openlayers 【入門教

    2024年04月13日
    瀏覽(24)
  • 【深入理解ES6】塊級作用域綁定

    【深入理解ES6】塊級作用域綁定

    提升(Hoisting)機(jī)制:通過var聲明的變量,都會(huì)被當(dāng)成在當(dāng)前作用域頂部生命的變量。 JavaScript引擎會(huì)將上面的getValue函數(shù)修改為下面這樣。變量value的聲明被提升至函數(shù)頂部,初始化操作依舊保留在原處執(zhí)行。為此,ES6引入了塊級作用域來強(qiáng)化對變量聲明周期的控制。

    2024年02月12日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包