Czy Mogę ustąpić z funkcji wewnętrznej?
Z generatorami ES6 widzę taki kod:
var trivialGenerator = function *(array) {
var i,item;
for(var i=0; i < array.length; i++){
item = array[i];
yield item;
};
};
Czy można zamiast tego napisać coś bardziej podobnego do poniższego kodu?
var trivialGenerator = function *(array) {
array.forEach(function *(item){
yield item;
});
};
Pytam, bo klasyczna pętla for
jest obrzydliwością.
2 answers
Nie, Nie możesz użyć yield
wewnątrz funkcji wewnętrznej. Ale w Twoim przypadku nie potrzebujesz go. Zawsze możesz użyć for-of
pętla zamiast forEach
metoda. Będzie wyglądać znacznie ładniej i można użyć continue
, break
, yield
w środku:
var trivialGenerator = function *(array) {
for (var item of array) {
// some item manipulation
yield item;
}
}
Możesz użyć for-of
, Jeśli masz jakieś manipulacje z przedmiotem w środku. W przeciwnym razie absolutnie nie musisz tworzyć tego generatora, ponieważ array
mA iterator
interfejs natywnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-30 06:37:15
Nie, Nie można ustąpić od wywołania zwrotnego(technicznie rzecz biorąc, nie jest to "funkcja wewnętrzna", co oznacza coś innego). Oczywiście nie ma sposobu, aby wywołać {[13] } z odpowiednikiem *
, lub, jeśli samo wywołanie zwrotne jest generatorem, aby powiedzieć forEach
aby wywołać wywołanie zwrotne z yield *
.
Jedną z alternatyw jest zapisanie funkcji forEachGen
w następujący sposób:
function *forEachGen(array, fn) { for (var i of array) yield *fn(i); }
Zasadniczo przeniesienie pętli for do forEachGen
. Definiowanie małego generatora próbek jako
function *yieldSelf(item) { yield item; }
forEachGen
będzie używany as
yield *forEachGen(array, yieldSelf);
Zakłada to, że wywołanie zwrotne jest generatorem, jak wydaje się sugerować, że chcesz w swoim przykładzie. Jeśli wywołanie zwrotne było ROF (zwykła stara funkcja), takie jak
function returnSelf(item) { return item; }
Wtedy będzie
function *forEachGen(array, fn) { for (var i of array) yield fn(i); }
Używany jako
yield *forEachGen(array, returnSelf);
Jeśli nie masz nic przeciwko dodaniu tego do prototypu tablicy, to
Object.defineProperty(Array.prototype, 'forEachGen', { value :
function *(fn) { for (i of this) yield fn(i); }
});
To zrób
yield *array.forEachGen(yieldSelf)
Możesz być zainteresowany http://fitzgen.github.io/wu.js / , która definiuje wrapper dla generatorów metodami takimi jako forEach
na opakowaniu.
async
/ await
Z await
, powinieneś być w stanie wykonać następujące czynności.
Zdefiniuj trywialne wywołanie zwrotne, które po prostu zwraca obietnicę dla siebie.
async function returnSelf(item) { return await item; }
forEachAsync
mapuje tablicę wejściową do tablicy obietnic i używa await *
do tworzenia i zwracania obietnicy dla wszystkich gotowych obietnic.
async function forEachAsync(values, fn) {
return await *values.map(returnSelf);
}
Możemy traktować wynik jako zwykłą obietnicę i wydrukować go w then
:
forEachAsync([1,2,3], returnSelf) .
then(result => console.log(result);
Lub użyć mały wrapper asynchroniczny, aby poczekać na wynik, a następnie wydrukować:
(async function() {
console.log(await forEachAsync([1,2,3], returnSelf));
})();
Testowane przy użyciu
babel-node --experimental test.js