ES6'nın ok işlevi sözdizimini jeneratörlerle kullanabilir miyim? (ok gösterimi)


243

yani bunu nasıl ifade ederim:

function *(next) {}

ile okları. Aklıma gelen tüm kombinasyonları denedim ve üzerinde herhangi bir belge bulamıyorum.

(şu anda v0.11.14 düğümü kullanılıyor)


5
Yapamazsın. Afedersiniz. function*Msgstr " İfade (yıldız işareti ile izlenen fonksiyon anahtar sözcüğü) bir jeneratör işlevi tanımlar."

2
Bu konuda esdiscuss.org adresinde biraz uzun bir tartışma olduğunu unutmayın .
voithos

4
Ne yapmayı param*=>{ }umuyorsun?
CoderPi

4
function(){}bunun aynı şeyi yapmadığını biliyor musunuz ()=>{}?
CoderPi

8
" Gerçekten ES6 jeneratörleri 2 adım ileri ve 1 adım geri mi? " - hayır, jeneratörler sadece ileri adım atabilir :-)
Bergi

Yanıtlar:


231

ES6'nın ok işlevi sözdizimini jeneratörlerle kullanabilir miyim?

Yapamazsın. Afedersiniz.

MDN'ye göre

function*(Deyim functionanahtar ardından yıldız işareti) bir jeneratör işlevi tanımlar.

Özel bir belgeden (benim vurguladığım):

Fonksiyon söz diziminin, bir isteğe bağlı ilave genişletilir *belirteci:

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

175
Bana bir tasarım kusuru gibi geliyor.
Jonathon

23
@Jonathon: Hayır. Ok işlevlerinin hafif olması (ve .prototypeörneğin olmaması ) ve genellikle tek gömlekli olması gerekirken, jeneratörler tam tersidir.
Bergi

38
Zaten oynadığım bir jeneratörün öncekine erişmesi gereken birkaç senaryo ile karşılaştım ve jeneratöre erişmek için kesmek thisyazmak zorunda kaldım let self = this. Sözcüksel kapsam + ok sözdizimi iyi olurdu. Talihsiz, ama tam olarak dünyanın sonu değil.
dvlsg

3
Bu konuda esdiscuss'ta
Nick Tomlin

20
Bergi ok fonksiyonlarının ardındaki mantık bundan çok daha karmaşıktır. Gerçekten kısalık ile ilgili değil. Ok işlevlerinin hafif olması gerekmez - isteğe bağlı tek deyimli bir vücut sözdizimi olduğu doğrudur, ama ne var. Birçok kişi, sınıf yöntemleri dışındaki tüm işlev tanımları için okları kullanır ve functionanahtar kelimeyi dilin 'kötü bir parçası' olarak gösterir. Bunu yapmak için iyi nedenler var. Bu insanlar için, ok üreticilerinin eksikliği can sıkıcı bir tutarsızlıktır.
callum

131

Satır içi işlevler ve Ok işlevleri arasındaki fark

Her şeyden önce Ok işlevleri () => {} , Satır İçi işlevlerin yerine geçmez function(){}ve farklıdır. Inline-Fonksiyonlar basitçe Fonksiyonlardır, bu yüzden soru Ok-fonksiyonları ve Inline-Fonksiyonları arasındaki farkın ne olduğudur.

Bir ok fonksiyonu ifadesi (ayrıca ok fonksiyonu olarak da bilinir) işlevi ifadeleri ile karşılaştırıldığında daha kısa sözdizimi vardır ve bağlamaz kendisine ait this, arguments, super, veya new.target). Ok işlevleri her zaman anonimdir.

Burada biraz daha hızlı ayrıntı


Ok işlevi neden jeneratör olarak kullanılamaz?

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

Ürün anahtar kelimesinin kullanımı

Verim anahtar kelime (ayrıca onun içinde yuvalanmış fonksiyonlar dahilinde izin hariç) bir ok işlevin vücudunda kullanılamaz. Sonuç olarak, ok işlevleri jeneratör olarak kullanılamaz.

O Not jeneratörler olmadan yieldifade etmiyor.


Ok işlevi neden verimi kullanamaz?

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

Fonksiyonlarını Ok bağlamak thislexically, bağlamak returniçinde Blok vücut halinde derhal çevreleyen ok fonksiyonu ve engel dan döner böylece breakve continuehemen çevreleyen ok fonksiyonu dışında ifadeleri başvuran dan.

Tanımlayıcı birincil ifade argumentsok işlevin vücudunda (ekspresyon ya da blok biçiminde olsun) kullanılmayabilir.

Benzer şekilde, yieldbir ok fonksiyonunun gövdesinde kullanılamaz. Oklar jeneratör olamaz ve derin devamlılıklar istemiyoruz.

Bir Ok İşlevindeki verim Anlamsal Hata verir: http://www.ecma-international.org/

Sonunda sebep ECMA6'nın uygulanmasındaki derin karmaşıklıktadır. C # buna benzer nedenlerle de izin vermez .


3
Bir arama motoru kullandım ve sizin için bir açıklama daha yayınladım
CoderPi

1
Hala açıklama eklemenin ()=>{}çok yardımcı olacağını, satır içi işlevden farkını anlamanın ve sınırlamanın neden üreticiler için olduğunu düşünüyorum.
vitaly-t

63
Neden iyi *() => { yield bla; }olmadığını anlamaya çalışıyorum , ama async () => { await bla; }...
Lee Benson

7
@CodeiSir, Re " ve derin devamlılıklar istemiyoruz ", berbat bahaneler.
Pacerier

9
Argümanınız döngüsel. Ok işlevlerinin oluşturucu olamayacağını söylüyorsunuz çünkü içlerinde verim anahtar sözcüğüne sahip olamıyorlar. Ancak verim anahtar kelimesine sahip olamazlar, çünkü üretici olamazlar: "Oklar üretici olamaz ve derin devamlılıklar istemiyoruz."
Thayne

35

Yukarıda bahsedilen Kasım 2013'ten esdiscuss.org ve Ecma TC39 komitesi ES6 toplantı notları hakkındaki tartışmaya ek olarak, iki Eylül 2016 tarihli ES7 toplantılarında jeneratör okları yeniden ziyaret edildi [1] [2] . Çeşitli sözdiziminin artıları ve eksileri (çoğunlukla =*>ve =>*) ve bu özellik için gerekçelerin ve kullanım durumlarının eksikliği hakkında bir tartışmadan sonra , şu sonuca vardılar:

  • Komiteden biraz ilgi var, ancak özelliğin yeni bir sözdizimi parçası eklemek için ağırlığını çekmemesi endişesi
  • =>*[Domenic Denicola] 'nın eşzamansız yineleme teklifinin bir parçası olarak, en azından 0. aşamaya geçip geçemeyeceğimizi görmek için 3. Gün yeniden ziyaret etmeyi planlayın

Jeneratör okları için teklif , Brendan Eich ve Domenic Denicola ile şampiyon olarak Aşama 1'e taşındı . Yukarıda belirtilen asenkron yineleme 2018'de tamamlandı ve uygulandı .

Ekim 2019'da Sergey Rubanov'un resmi bir repo sözdizimi ve diğer ayrıntılar hakkında daha fazla tartışma ile ortaya çıktı.


8

Ben de aynı soruyu soruyordum ve buraya geldim. Mesajları ve yorumları okuduktan sonra, bir ok fonksiyonunda jeneratör kullanmanın belirsiz olduğunu hissettim:

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

Bu, ok fonksiyonu ile ilgili olarak jeneratörü uygulamamalarının en büyük nedeni olabilir.


Ama onlardan biri olsaydım şöyle düşünebilirdim:

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

Bu, asenkron fonksiyonumuz varmış gibi geliyor:

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

Çünkü, normal işlevle async anahtar sözcüğü var, bu nedenle ok işlevi onu kullanıyor - async () =>büyük olasılıkla görünecek async function().

Ancak, genveya gibi bir anahtar kelime yoktur generatorve ne yazık ki ok işlevi bunu kullanmıyor.

Sonuç olarak:

Jeneratörü ok fonksiyonunda uygulamak isteseler bile, çekirdek js'deki jeneratör sözdizimini yeniden düşünmeleri gerektiğini düşünüyorum:

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

Ve bu büyük bir gaf olacak. Yani, ok fonksiyonunu jeneratörden uzak tutmak oldukça havalı.


@Bergi yorumu takip ediliyor :

Hayır. Ok işlevlerinin hafif olması (ve örneğin bir .prototipinin olmaması) ve genellikle tek katmanlı olması gerekirken, jeneratörler hemen hemen tam tersidir.

Jeneratör kullanım amacının run-stop-run olduğunu söyleyeceğim ve bu yüzden prototip, sözcüksel vb.


2
Ayrıca egzotik seçenekleri de düşünebiliriz () ~> { yield 'a'; yield 'b'; }. Dürüst olmak gerekirse, sadece tildleri seviyorum.
Gershom

@Gershom Perl gibi programlama dilleri tamamen yanlış gidiyor
Sapphire_Brick

2

Bunun çok geç olduğunu biliyorum, ancak başka bir olası neden sözdizimi olabilir. belki (*() => {})işe yarar, ama ne olacak (9 ** () => {})? Bu 9 geri dönen bir ok fonksiyonunun gücüne NaNmi, yoksa geri dönen bir jeneratör ok fonksiyonunun 9 katı NaNmı? Bu, =>*burada başka bir cevapta belirtildiği gibi bazı alternatif sözdizimi ile yapılabilir , ancak belki de jeneratör işlevi sözdiziminin (örn. function* () {}Ve { *genMethod() {} }uygulandığı sırada) tutarlılığını koruma arzusu vardı . Çok fazla bir mazeret değil, bunun bir nedeni.


1
: +1: çifte yıldız için ... Eski JS JS adamý. Kim eski bir köpeğe yeni numaralar öğretemeyeceğini söyleyen: sevinç:
Shanimal

Bunu yapmamalarının tek nedeni, ayrıştırıcıyı zor yapmaktır. Bu tamamen mümkündür ve sözdiziminden ödün verilmesini gerektirmez.
Jason McCarrell

@JasonMcCarrell Ayrıştırıcıyı çok karmaşık hale getirmemekle yeteri kadar ilgilendiyse, belki Brendan Eich'in Şemayı tarayıcıya koyması gerekirdi.
Sapphire_Brick

1

Şu anda yapamazsınız, ancak gelecekte olabilirsiniz çünkü TC39 , 2019 yılının Ekim ayında aynı olan 1. aşamadaki teklifini yayınlayabilir .


-4

Redux-saga ile güzel bir çözüm var

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

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

4
OP'nin Redux kullandığını nasıl bilebiliriz?
Maros
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.