ฉันสามารถใช้ไวยากรณ์ฟังก์ชั่นลูกศรของ ES6 กับเครื่องกำเนิดไฟฟ้าได้หรือไม่? (เครื่องหมายลูกศร)


243

ฉันจะอธิบายสิ่งนี้อย่างไร:

function *(next) {}

ด้วยลูกศร ฉันลองชุดค่าผสมทั้งหมดที่ฉันสามารถนึกได้และไม่พบเอกสารใด ๆ

(ปัจจุบันใช้โหนด v0.11.14)


5
คุณทำไม่ได้ ขอโทษ " function*คำสั่ง (ฟังก์ชั่นคีย์เวิร์ดตามด้วยเครื่องหมายดอกจัน) กำหนดฟังก์ชั่นเครื่องกำเนิด"

2
โปรดทราบว่ามีการอภิปรายค่อนข้าง-ยาวในหัวข้อนี้ที่ esdiscuss.org
voithos

4
คุณคาดหวังว่าparam*=>{ }จะทำอะไร?
CoderPi

4
คุณรู้หรือfunction(){}ไม่ว่าไม่ทำเช่นเดียวกัน()=>{}?
CoderPi

8
" เป็นจริงหรือไม่ที่เครื่องกำเนิดไฟฟ้า ES6 นั้นเดินไปข้างหน้า 2 ก้าวและถอยกลับ 1 ก้าว " - ไม่เครื่องปั่นไฟสามารถก้าวไปข้างหน้าเท่านั้น :-)
Bergi

คำตอบ:


231

ฉันสามารถใช้ไวยากรณ์ฟังก์ชั่นลูกศรของ ES6 กับเครื่องกำเนิดไฟฟ้าได้หรือไม่?

คุณทำไม่ได้ ขอโทษ

ตามMDN

function*คำสั่ง ( functionตามคำหลักด้วยเครื่องหมายดอกจัน) กำหนดฟังก์ชั่นเครื่องกำเนิดไฟฟ้า

จากเอกสารข้อมูลจำเพาะ (ความสำคัญของฉัน):

ฟังก์ชั่นไวยากรณ์จะขยายเพื่อเพิ่มตัวเลือก*โทเค็น:

FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")" 
  "{" FunctionBody "}"

175
รู้สึกเหมือนข้อบกพร่องในการออกแบบสำหรับฉัน
Jonathon

23
@ Jonathon: ไม่ฟังก์ชั่น Arrow ควรจะมีน้ำหนักเบา (และไม่มี.prototypeตัวอย่าง) และมักจะมีหนึ่ง liners ในขณะที่เครื่องกำเนิดไฟฟ้าค่อนข้างตรงกันข้าม
Bergi

38
ฉันได้ทำงานข้ามบางสถานการณ์ที่ตัวสร้างที่ฉันเล่นด้วยการเข้าถึงที่จำเป็นก่อนหน้านี้thisและต้องเขียนlet self = thisแฮ็กเพื่อเข้าถึงภายในตัวสร้าง ไวยากรณ์ขอบเขต + ลูกศรศัพท์น่าจะดี โชคร้าย แต่ไม่ใช่จุดจบของโลก
dvlsg

3
บริบทเพิ่มเติมเกี่ยวกับเรื่องนี้ที่esdiscuss
Nick Tomlin

20
@Bergi เหตุผลเบื้องหลังฟังก์ชั่นลูกศรนั้นซับซ้อนกว่านั้นมาก มันไม่ได้เกี่ยวกับความกะทัดรัด ฟังก์ชั่นลูกศรไม่จำเป็นต้องมีน้ำหนักเบา - มันเป็นความจริงมีซินแทกซ์คำสั่งเดียวที่เป็นตัวเลือก หลายคนใช้ลูกศรสำหรับคำนิยามฟังก์ชั่นทั้งหมดยกเว้นวิธีการเรียนและลดระดับfunctionคำหลักเพื่อเป็น 'ส่วนที่ไม่ดี' ของภาษา มีเหตุผลที่ดีในการทำเช่นนี้ สำหรับคนเหล่านี้การขาดเครื่องกำเนิดลูกศรเป็นสิ่งที่ไม่สอดคล้องกันที่น่ารำคาญ
callum

131

ความแตกต่างระหว่างฟังก์ชั่นอินไลน์และฟังก์ชั่นลูกศร

ประการแรกฟังก์ชั่นลูกศร ทั้งหมด() => {}ไม่ได้ทำขึ้นเพื่อแทนที่ฟังก์ชั่นอินไลน์function(){}และมีความแตกต่างกัน ฟังก์ชั่นอินไลน์เป็นเพียงฟังก์ชั่นดังนั้นคำถามคือความแตกต่างระหว่างฟังก์ชั่นลูกศรและฟังก์ชั่นอินไลน์คืออะไร

ฟังก์ชั่นการแสดงออกศร (หรือเรียกว่าฟังก์ชั่นลูกศร) มีไวยากรณ์สั้นเมื่อเทียบกับการแสดงออกและฟังก์ชั่นไม่ได้ผูกของตัวเองthis, arguments, superหรือnew.target) ฟังก์ชั่นลูกศรไม่ระบุชื่อเสมอ

ดูรายละเอียดเพิ่มเติมได้ที่นี่


เหตุใด Arrow-function จึงไม่สามารถใช้เป็นเครื่องกำเนิดไฟฟ้าได้

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

การใช้คำหลักผลตอบแทน

ผลผลิตคำหลักอาจไม่สามารถใช้ในร่างกายของฟังก์ชั่นของลูกศร (ยกเว้นเมื่อได้รับอนุญาตภายในฟังก์ชั่นเพิ่มเติมที่ซ้อนกันอยู่ภายใน) ดังนั้นฟังก์ชั่นลูกศรจึงไม่สามารถใช้เป็นเครื่องกำเนิดไฟฟ้าได้

โปรดทราบว่าเครื่องกำเนิดไฟฟ้าที่ไม่มีyieldความหมาย


เหตุใดฟังก์ชันลูกศรจึงไม่สามารถใช้ผลตอบแทนได้

http://tc39wiki.calculist.org/es6/arrow-functions/

ฟังก์ชั่นลูกศรผูกคำthisศัพท์ผูกreturnในกรณีที่ร่างกายบล็อกดังนั้นมันกลับมาจากฟังก์ชั่นลูกศรล้อมรอบทันทีและป้องกันbreakและcontinueจากการอ้างอิงคำสั่งนอกฟังก์ชั่นลูกศรล้อมรอบทันที

ตัวบ่งชี้การแสดงออกหลักargumentsอาจไม่สามารถใช้ในร่างกายของฟังก์ชั่นของลูกศร (ไม่ว่าจะแสดงออกหรือรูปแบบบล็อก)

ในทำนองเดียวกันyieldอาจไม่สามารถใช้ในร่างกายของฟังก์ชั่นลูกศร ลูกศรไม่สามารถเป็นเครื่องกำเนิดไฟฟ้าได้และเราไม่ต้องการความต่อเนื่องในเชิงลึก

ผลตอบแทนในฟังก์ชั่นลูกศรจะทำให้เกิดข้อผิดพลาดทางความหมาย: http://www.ecma-international.org/

ในที่สุดเหตุผลก็คือความซับซ้อนในการใช้ ECMA6 C # จะไม่ปล่อยให้เรื่องนี้เป็นอย่างดีสำหรับค่อนข้างคล้ายเหตุผล


3
ฉันใช้เครื่องมือค้นหาและโพสต์อีกหนึ่งคำอธิบายให้คุณ
CoderPi

1
ฉันยังคิดว่าการเพิ่มคำอธิบายเกี่ยวกับ()=>{}จะช่วยได้มากทำความเข้าใจกับความแตกต่างจากฟังก์ชั่นในบรรทัดและทำไมข้อ จำกัด มีสำหรับเครื่องกำเนิดไฟฟ้า
vitaly-t

63
ฉันพยายามคิดออกว่าทำไม*() => { yield bla; }ไม่โอเค แต่async () => { await bla; }เป็น ...
Lee Benson

7
@CodeiSir, Re " และเราไม่ต้องการต่อเนื่องลึก " แก้ตัวหมัด
Pacerier

9
อาร์กิวเมนต์ของคุณเป็นวัฏจักร คุณบอกว่าฟังก์ชั่นลูกศรไม่สามารถเป็นเครื่องกำเนิดไฟฟ้าได้เพราะพวกมันไม่มีคีย์เวิร์ดผลผลิตในนั้น แต่พวกเขาไม่สามารถมีคำหลักที่ให้ผลตอบแทนเพราะพวกเขาไม่สามารถเป็นเครื่องกำเนิดไฟฟ้า: "ลูกศรไม่สามารถเป็นเครื่องกำเนิดไฟฟ้าได้และเราไม่ต้องการความต่อเนื่องในเชิงลึก"
Thayne

35

นอกจากนี้ในการอภิปรายในesdiscuss.orgและEcma TC39 คณะกรรมการ ES6 บันทึกการประชุมจากพฤศจิกายน 2013ดังกล่าวข้างต้นกำเนิดลูกศรถูกเยือนในสองกันยายน 2016 ES7 ประชุม[1] [2] หลังจากการอภิปรายเกี่ยวกับข้อดีข้อเสียของไวยากรณ์ต่าง ๆ (ส่วนใหญ่=*>และ=>*) และการขาดการให้เหตุผลและการใช้กรณีสำหรับคุณลักษณะนี้พวกเขามาถึงข้อสรุปที่:

  • มีความสนใจจากคณะกรรมการบ้าง แต่กังวลว่าฟีเจอร์นี้จะไม่ดึงน้ำหนักเพื่อเพิ่มไวยากรณ์ใหม่
  • วางแผนที่จะกลับมาเยี่ยมชมในวันที่ 3 เพื่อดูว่าเราจะ=>*ไปถึงขั้นที่ 0 เป็นอย่างน้อยหรือไม่ซึ่งเป็นส่วนหนึ่งของข้อเสนอการทำซ้ำแบบซิงโครไนซ์ของ Domenic Denicola

ข้อเสนอสำหรับลูกศรกำเนิดถูกย้ายไปยังด่าน1โดยเบรนแดนไอชและโดเมนิกเดนิโคลาเป็นผู้ชนะ การทำซ้ำแบบอะซิงโครนัสที่กล่าวถึงข้างต้นเสร็จสิ้นและนำไปใช้ในปี 2018

ในเดือนตุลาคมปี 2019 มีการซื้อคืนอย่างเป็นทางการโดย Sergey Rubanovปรากฏขึ้นพร้อมกับการอภิปรายเพิ่มเติมเกี่ยวกับไวยากรณ์และรายละเอียดอื่น ๆ


8

ฉันยังมีคำถามเดียวกันและมาที่นี่ หลังจากอ่านโพสต์และความคิดเห็นฉันรู้สึกว่าการใช้เครื่องกำเนิดไฟฟ้าในฟังก์ชั่นลูกศรดูเหมือนจะคลุมเครือ:

const generator = () => 2*3; // * implies multiplication
// so, this would be a confusing
const generator = () =>* something; // err, multiplying?
const generator = () =*> ... // err, ^^
const generator = ()*=> ... // err, *=3, still multiplying?
const generator=*()=> ... // err, ^^
const generator = *param => ... //err, "param" is not fixed word

นี่คือสิ่งที่อาจเป็นเหตุผลใหญ่ที่พวกเขาไม่ได้ใช้เครื่องกำเนิดไฟฟ้าที่เกี่ยวข้องกับฟังก์ชั่นลูกศร


แต่ถ้าฉันเป็นหนึ่งในพวกเขาฉันอาจคิดแบบนี้:

const generator = gen param => ... // hmm, gen indicates a generator
const generator = gen () => ... // ^^

นี่รู้สึกเหมือนกับว่าเรามีฟังก์ชั่นแบบอะซิงโครนัส:

const asyncFunction = async () => ... // pretty cool

เพราะด้วยฟังก์ชั่นปกติมีคำหลักasyncอยู่ดังนั้นฟังก์ชั่นลูกศรจึงใช้มัน - async () =>ดูเหมือนจะเป็นไปasync function()ได้

แต่ไม่มีคำหลักที่ชอบgenหรือgeneratorและฟังก์ชั่นลูกศรไม่ได้ใช้มัน

สรุป:

แม้ว่าพวกเขาต้องการที่จะใช้เครื่องกำเนิดไฟฟ้าในฟังก์ชั่นลูกศรฉันคิดว่าพวกเขาต้องคิดใหม่เกี่ยวกับไวยากรณ์ของเครื่องกำเนิดไฟฟ้าใน core js:

generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}

และนี่จะเป็นความผิดพลาดครั้งใหญ่ ดังนั้นการรักษาฟังก์ชั่นลูกศรออกจากเครื่องกำเนิดไฟฟ้าก็ค่อนข้างดี


กำลังติดตามความคิดเห็น @Bergi :

ไม่ได้ฟังก์ชั่น Arrow นั้นควรจะมีน้ำหนักเบา (และไม่มีตัวอย่างต้นแบบ) และมักจะเป็น liners หนึ่งตัวในขณะที่เครื่องกำเนิดไฟฟ้าค่อนข้างตรงกันข้าม

ฉันจะบอกว่าจุดประสงค์ของตัวสร้างที่จะใช้คือrun-stop-runและดังนั้นฉันไม่คิดว่าเราจำเป็นต้องใส่ใจกับต้นแบบ, คำศัพท์นี้เป็นต้น


2
() ~> { yield 'a'; yield 'b'; }อาจจะพิจารณาตัวเลือกที่แปลกใหม่ด้วยเช่น พูดตามตรงฉันแค่รักตัวหนอน
Gershom

@Gershom นี่คือวิธีการเขียนโปรแกรมภาษาเช่นPerlผิดไปทั้งหมด
Sapphire_Brick

2

ฉันรู้ว่านี่มันช้ามาก แต่อีกสาเหตุที่เป็นไปได้คือไวยากรณ์ อาจจะ(*() => {})ทำงาน แต่สิ่งที่เกี่ยวกับ(9 ** () => {})? คือการที่ 9 ถึงพลังของฟังก์ชั่นที่ลูกศรกลับNaNหรือจะเป็นครั้งที่ 9 กำเนิดลูกศรฟังก์ชั่นยังกลับมาNaN? มันสามารถทำได้ด้วยไวยากรณ์ทางเลือกบางอย่างเช่น=>*ที่กล่าวถึงโดยคำตอบอื่นที่นี่ แต่อาจมีความปรารถนาที่จะรักษาความมั่นคงของไวยากรณ์ฟังก์ชั่นเครื่องกำเนิด (เช่นfunction* () {}และ{ *genMethod() {} }) เมื่อมันถูกนำมาใช้ ไม่ใช่ข้อแก้ตัวที่มากเกินไป แต่เป็นเหตุผลสำหรับมัน


1
: +1: สำหรับเครื่องหมายดอกจันคู่ ... เด็กชายโรงเรียน JS เก่าที่นี่ ใครบอกว่าคุณไม่สามารถสอนลูกเล่นใหม่ ๆ เกี่ยวกับสุนัข: ความสุข:
Shanimal

เหตุผลเดียวที่พวกเขาไม่ทำเพราะการแยกวิเคราะห์เป็นเรื่องยาก เป็นไปได้ทั้งหมดและไม่ต้องการการประนีประนอมในไวยากรณ์
Jason McCarrell

@JasonMcCarrell หากพวกเขาสนใจพอที่จะไม่แยกวิเคราะห์ข้อความซับซ้อนเกินไปบางทีเบรนแดนไอชควรใส่ Scheme ลงในเบราว์เซอร์
Sapphire_Brick


-4

มีวิธีแก้ปัญหาที่ดีกับ redux-saga

import { call, all } from 'redux-saga/effects';

function* gen() {
   yield all([].map(() => {
      return call(....);
   }));
}

4
เราจะรู้ได้อย่างไรว่า OP กำลังใช้ Redux อยู่?
Maros
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.