Cet article vous apporte une introduction à l'utilisation du générateur ES6 (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Concept
Un générateur est obtenu en exécutant une fonction génératrice et est itérable.
function* gen() { yield 'a'; yield 'b'; yield 'c'; } let g = gen(); // "Generator { }"
Principe et application simple
Le générateur a une fonctionnalité intéressante, il peut mettre en pause l'exécution du code interne et renvoyer une valeur à la fonction externe. (Après la pause, l'exécution d'autres codes ne sera pas empêchée.) Lorsque sa prochaine méthode est appelée en externe, elle continuera à exécuter le code restant et acceptera un paramètre de l'extérieur. Cette implémentation repose principalement sur le mot clé rendement .
Le mot-clé rendement provoque la pause de l'exécution de la fonction du générateur et la valeur de l'expression suivant le mot-clé rendement est renvoyée à l'appelant du générateur. Il peut être considéré comme une version basée sur un générateur du mot-clé return.
function* g(){ var a = yield 2; console.log(a); } var it = g(); // 返回一个可迭代的生成器对象 console.log(it.next()); // 执行生成器函数内部代码,第一次返回 {done: false, value: 2} it.next(3); // 继续执行生成器函数内部代码,同时向生成器传递参数3,最后返回 {done: true, value: undefined}
Un compteur simple
function* count(){ var n = 1; while(true){ yield n++; } } var it = count(); it.next(); // 1 it.next(); // 2 it.next(); // 3
Écrire du code asynchrone de manière synchrone
Ajax asynchrone précédemment géré Le résultat de la requête est généralement transmis par une fonction de rappel. Une fois que vous rencontrez plusieurs niveaux d'imbrication de rappel, la lisibilité du code sera réduite et le débogage sera peu pratique. Avec le générateur, nous pouvons écrire du code asynchrone de manière synchrone. Cela semble très intéressant. Notre code ressemblera à ceci
function foo(){ var result = asyncFun(); // asyncFun 是异步函数,result 是异步返回的结果 console.log(result); }
Bien sûr, le code ci-dessus n'obtient pas le résultat correct, c'est juste une idée. Nous allons le faire avec des générateurs, et ça marche. Pensez aux caractéristiques du générateur :
Ça suffit. Avec la fonction générateur en place, nous repensons maintenant le code :
function* foo(){ // 这里遇到了异步方法,必须停下来。 // 等待异步方法执行完毕,并返回结果,继续运行代码。当然,同步 ajax 不能算,它不是异步 // 输出结果 }
Arrêtez-vous et réfléchissez aux mots-clés liés à pause et continuer. Arrêtez... continuez... arrêtez... continuez... arrêtez... continuez...Ne pas... Arrêter... Ne pas... Arrêter... Ne pas ...Stop...ces deux mots sont rendement, suivant.
function *foo(){ var result = yield asyncFun(next); console.log(result); }
lorsque le code rencontre rendement sera mise en pause. À ce moment, la fonction asyncFun ne sera pas mise en pause, mais sera exécutée une fois l'exécution terminée, la méthode next du générateur sera appelée et renverra le résultat. est passé à next en paramètre. Puisque nous ne pouvons pas obtenir next dans la fonction génératrice, nous devons utiliser des variables globales pour passer next.
var next, gn; function asyncFun(next){ // 模拟异步请求 setTimeout(function(){ // 返回一个随机数 next(Math.random()) }, 1000) } function* foo(){ var result = yield asyncFun(next); console.log(result); } gn = foo(); next = gn.next.bind(gn); next(); // 打印随机数
Écrit comme ça, ça paraît un peu lourd à gérer. Vous pouvez écrire une fonction wrapper pour exécuter une fonction génératrice contenant du code asynchrone.
function asyncFun(next){ // 模拟异步请求 setTimeout(function(){ // 返回一个随机数 next(Math.random()) }, 1000) } function* foo(){ var result = yield function(next){asyncFun(next)}; console.log(result); } function wrapFun (gFn){ var gn = foo(), next = gn.next.bind(gn); next().value(next); } wrapFun(foo);
Cependant, depuis l'introduction de Promise et attendez, de plus en plus de personnes utilisent Cette combinaison est plus simple à utiliser et offre une portée plus large.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!