Heim  >  Artikel  >  Web-Frontend  >  Mein Node.js-Lernpfad (3) – Node.js-Funktionen, Rückrufe, synchroner und asynchroner Code und Ereignisloop_node.js

Mein Node.js-Lernpfad (3) – Node.js-Funktionen, Rückrufe, synchroner und asynchroner Code und Ereignisloop_node.js

WBOY
WBOYOriginal
2016-05-16 16:42:352011Durchsuche

1. Die Rolle von node.js,

Die Bedeutung von I/O (I/O ist die Abkürzung für Eingabe/Ausgabe, z. B.: Geben Sie Text auf der Tastatur ein, geben Sie ein, sehen Sie sich die Textausgabe auf dem Bildschirm an. Bewegen Sie die Maus und sehen Sie die Bewegung der Maus auf dem Bildschirm und die gesehene Ausgabe usw.)

Die Probleme, die node.js lösen möchte (Verarbeitung von Eingaben, Eingaben, hohe Parallelität. Beispielsweise kann es Millionen von Spielern in einem Online-Spiel geben, es gibt Millionen von Eingaben usw.) (Kategorien, für die node.js geeignet ist : wenn Node.js am besten geeignet ist, wenn die Anwendung Daten über das Netzwerk senden und empfangen muss. Dies kann eine Drittanbieter-API, ein vernetztes Gerät oder eine Echtzeitkommunikation zwischen dem Browser und dem Server sein)

Die Bedeutung von Parallelität (der Begriff Parallelität beschreibt Dinge, die zur gleichen Zeit passieren und möglicherweise miteinander interagieren). Das Evented-I/O-Modell von Node ermöglicht es uns, uns keine Gedanken über Verriegelung und Parallelität zu machen, die bei asynchronen Multithread-E/A-Vorgängen üblich sind. O Frage)

Demo-Netzwerk-E/A

Js-Code

var http = require('http'), 
  urls = ['www.baidu.com','www.10jqka.com.cn','www.duokan.com']; 
function fetchPage(url){ 
  var start = new Date(); 
  http.get({host:url},function(res){ 
    console.log("Got response from:" + url); 
    console.log("Request took:",new Date() - start, "ms"); 
  }); 
} 
for(var i=0; i<urls.length; i++){ 
  fetchPage(urls[i]); 
} 

Benannt, node.js
Wir führen node node.js
im Terminal aus Ausgabe:

Wir bitten node.js, auf drei URLs zuzugreifen und die erhaltene Antwort und die dafür benötigte Zeit zu melden.
Wir können sehen, dass die beiden Ausgabezeiten unterschiedlich sind. Wird von verschiedenen Faktoren beeinflusst, z. B. der Zeit zur Lösung von DNS-Anfragen, Server-Auslastungsverfahren usw.

Warum JavaScript eine ereignisgesteuerte Sprache ist
JavaScript basiert auf Ereignissen, die ursprünglich mit dem Document Object Model (DOM) verknüpft waren. Entwickler können Dinge tun, wenn Ereignisse auftreten. Zu diesen Ereignissen gehören das Klicken des Benutzers auf ein Element, der Abschluss des Ladevorgangs der Seite usw. Mithilfe von Ereignissen können Entwickler Ereignis-Listener schreiben, die beim Eintreten eines Ereignisses ausgelöst werden.

2. Rückruf
1. Was ist ein Rückruf?
2. Rückrufe analysieren

Ein Rückruf bezieht sich auf die Übergabe einer Funktion als Argument an eine andere Funktion und wird normalerweise aufgerufen, nachdem die erste Funktion abgeschlossen ist.

Beispiel: Wie die Methode hide() in jquery,
Js-Code

1,$("p").hide('slow'); 
2,$("p").hide('slow',function(){alert("The paragraph is now hidden")}); 

Rückrufe sind optional,
1 Kein Rückruf erforderlich
2. Es erfolgt ein Rückruf. Wenn der Absatz ausgeblendet ist, wird er aufgerufen und eine Warnmeldung angezeigt.

So können Sie den Unterschied zwischen Code mit und ohne Rückrufe erkennen
Js-Code

$("p").hide('slow'); 
alert("The paragraph is now hidden");//1 
 
$("p").hide('slow',function(){alert("The paragraph is now hidden")});//2 

1, es gibt keinen Rückruf und die Ausführungsreihenfolge ist dieselbe. Wir können jedoch sehen, dass der p-Absatz nicht vollständig ausgeblendet ist und die Warnung ausgegeben wird
2. Es gibt einen Rückruf und die Ausführung ist in Alarmbereitschaft
, nachdem das Ausblenden abgeschlossen ist.
Rückrufe analysieren
Js-Code

function haveBreakfast(food,drink,callback){ 
  console.log('Having barakfast of' + food + ', '+ drink); 
  if(callback && typeof(callback) === "function"){ 
    callback(); 
  } 
} 
 
haveBreakfast('foast','coffee',function(){ 
  console.log('Finished breakfast. Time to go to work!'); 
}); 


Ausgabe:

Having barakfast of foast,coffee
Finished breakfast. Time to go to work!

Hier ist eine Funktion, die mit drei Parametern erstellt wurde. Der dritte Parameter ist Callback. Dieser Parameter muss eine Funktion sein.
Die haveBreakfast-Funktion protokolliert, was gegessen wird, in der Konsole und ruft dann die als Parameter übergebene Callback-Funktion auf.

So verwenden Sie Rückrufe in Node.js

Beispiel für die Verwendung des Dateisystemmoduls zum Lesen von Dateiinhalten von der Festplatte in node.js

Js-Code

var fs = require('fs'); 
 
fs.readFile('somefile.txt','utf8',function(err,data){ 
  if(err) throw err; 
  console.log(data); 
});

Das Ergebnis ist: der Inhalt in somefile.txt.
1. Das fs-Modul (Dateisystem) wird zur Verwendung in Skripten
angefordert 2. Geben Sie den Dateipfad im Dateisystem als ersten Parameter für die fs.readFile-Methode
an 3. Der zweite Parameter ist utf8, der die Kodierung der Datei
darstellt 4. Stellen Sie die Callback-Funktion als dritten Parameter für die fs.readFile-Methode
bereit 5. Der erste Parameter der Rückruffunktion ist err, der zum Speichern des Fehlers verwendet wird, der beim Lesen der Datei
zurückgegeben wird 6. Der zweite Parameter der Rückruffunktion besteht darin, die beim Lesen der Datei zurückgegebenen Daten zu speichern.
7. Sobald die Datei gelesen wurde, wird der Rückruf
aufgerufen 8. Wenn err wahr ist, wird ein Fehler ausgegeben
9. Wenn err falsch ist, können die Daten aus der Datei verwendet werden
10. In diesem Beispiel werden die Daten in der Konsole protokolliert.

Ein weiteres Modul, das http-Modul, ermöglicht Entwicklern die Erstellung von http-Clients und -Servern.

Js-Code

var http = require('http'); 
 
http.get({host:'shapeshed.com'},function(res){ 
  console.log("Got response:" + res.statusCode); 
}).on('error',function(e){ 
  console.log("Got error:" + e.message); 
 
}); 

Ergebnis: Antwort erhalten: 200
1. Fordern Sie das http-Modul zur Verwendung in Skripten an
2. Geben Sie zwei Parameter für die http.get()-Methode
an 3. Der erste Parameter ist das Optionsobjekt. In diesem Beispiel wird die Homepage von shapeshed.com
angefordert 4. Der zweite Parameter ist eine Callback-Funktion, die die Antwort als Parameter
übernimmt 5. Wenn der Remote-Server die Antwort zurückgibt, wird die Rückruffunktion ausgelöst.
6. Notieren Sie den Antwortstatuscode in der Rückruffunktion. Wenn ein Fehler auftritt, können Sie ihn aufzeichnen.

Schauen wir uns als Nächstes vier verschiedene E/A-Vorgänge an, die alle Rückrufe verwenden

Js-Code

var fs = require('fs'), 
  http = require('http'); 
 
http.get({host:'www.baidu.com'},function(res){ 
  console.log("baidu.com"); 
}).on('error',function(e){ 
  console.log("Got error:" + e.message); 
 
}); 
 
fs.readFile('somefile.txt','utf8',function(err,data){ 
  if(err) throw err; 
  console.log("somefile"); 
}); 
 
http.get({host:'www.duokan.com'},function(res){ 
  console.log("duokan.com"); 
}).on('error',function(e){ 
  console.log("Got error:" + e.message); 
 
}); 
 
fs.readFile('somefile2.txt','utf8',function(err,data){ 
  if(err) throw err; 
  console.log("somefile2"); 
}); 

 我们能知道哪个操作先返回吗?
猜测就是从磁盘上读取的两个文件先返回,因为无需进入网络,但是我们很难说哪个文件先返回,因为我们不知道文件的大小。对于两个主页的获取,脚本要进入网络,而响应时间则依赖于许多难以预测的事情,Node.js进程在还有已经注册的回调尚未触发之前将不会退出。回调首先解决不可预测性的方法,他也是处理并发(或者说一次做超过一件事情)的高效方法。
下面是我执行的结果


  
 同步和异步代码 

先看代码,同步(或者阻塞)代码

Js代码 

function sleep(milliseconds){ 
  var start = new Date().getTime(); 
  while((new Date().getTime() -start) < milliseconds){ 
 
  } 
} 
function fetchPage(){ 
  console.log('fetching page'); 
  sleep(2000); 
  console.log('data returned from requesting page'); 
} 
function fetchApi(){ 
  console.log('fetching api'); 
  sleep(2000); 
  console.log('data returned from the api'); 
} 
fetchPage(); 
fetchApi(); 

 
当脚本运行时,fetchPage()函数会被调用,直到它返回之前,脚本的运行是被阻塞的,在fetchPage()函数返回之前,程序是不能移到fetchApi()函数中的。这称为阻塞操作。
Node.js几乎从不使用这种编码风格,而是异步地调用回调。
看下下面编码,,

Js代码 

var http = require('http'); 
 
function fetchPage(){ 
  console.log('fetching page'); 
  http.get({host:'www.baidu.com',path:'/&#63;delay=2000'}, 
    function(res){ 
      console.log('data returned from requesting page'); 
    }).on('error',function(e){ 
      console.log("There was an error" + e); 
    }); 
} 
function fetchApi(){ 
  console.log('fetching api'); 
  http.get({host:'www.baidu.com',path:'/&#63;delay=2000'}, 
    function(res){ 
      console.log('data returned from requesting api'); 
    }).on('error',function(e){ 
      console.log("There was an error" + e); 
    }); 
} 
fetchPage(); 
fetchApi(); 

 允许这段代码的时候,就不再等待fetchPage()函数返回了,fetchApi()函数随之立刻被调用。代码通过使用回调,是非阻塞的了。一旦调用了,两个函数都会侦听远程服务器的返回,并以此触发回调函数。
注意这些函数的返回顺序是无法保证的,而是和网络有关。
 
事件循环

Node.js使用javascript的事件循环来支持它所推崇的异步编程风格。基本上,事件循环使得系统可以将回调函数先保存起来,而后当事件在将来发生时再运行。这可以是数据库返回数据,也可以是HTTP请求返回数据。因为回调函数的执行被推迟到事件反生之后,于是就无需停止执行,控制流可以返回到Node运行时的环境,从而让其他事情发生。

Node.js经常被当作是一个网络编程框架,因为它的设计旨在处理网络中数据流的不确定性。促成这样的设计的是事件循环和对回调的使用,他们似的程序员可以编写对网络或I/O事件进行响应的异步代码。

需要遵循的规则有:函数必须快速返回,函数不得阻塞,长时间运行的操作必须移到另一个进程中。
Node.js所不适合的地方包括处理大量数据或者长时间运行计算等。Node.js旨在网络中推送数据并瞬间完成。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn