NodeJS實現同步的方法

來源:互聯網
上載者:User

標籤:inter   number   cte   keyword   問題   對象   title   play   nod   

 

NodeJS被打上了單線程、非阻塞、事件驅動…..等標籤。 在單線程的情況下,是無法開啟子線程的。經過了很久的研究,發現並沒有thread函數!!!但是有時候,我們確實需要“多線程”處理事務。nodeJS有兩個很基礎的api:setTimeout和setInterval。這兩個函數都能實現“非同步”。 nodeJS的非同步實現:nodeJS有一個任務隊列,在使用setInterval函數的時候,會每隔特定的時間向該任務隊列增加任務,從而實現“多任務”處理。但是,“特定的時間”不代表是具體的時間,也有可能是會大於我們設定的時間,也有可能小於。 我們跑跑下面代碼塊

setInterval(function() {    console.log(new Date().getTime());}, 1000);

 

輸出的結果如下:

14905313906401490531391654149053139266014905313936651490531394670149053139567014905313966721490531397675......

 

我們可以看到,所有的時間間隔都是不一樣的。時間的位移不僅包含了間隔的1s,還包含了console.log()的耗時,以及new Date()的耗時。在大量的資料統計下,時間間隔近似於1s。

問題來了,setInterval是能實現多任務的效果,但是怎樣才能實現任務之間的同步操作呢?這裡實現的方法是通過回呼函數實現的。

function a(callback) {    // 類比任務a耗時    setTimeout(function() {        console.log("task a end!");        // 回調任務b        callback();    }, 3000);};function b() {    setTimeout(function() {        console.log("task b end!");    }, 5000);}a(b);

 

這裡舉了一個很簡單的例子,就是將b方法的實現賦值給a方法的callback函數從而實現函數回調,但是會有個問題。假設a方法依賴於b方法,b方法依賴於c方法,c方法依賴於d方法…..也就意味著每個方法的實現都需要持有上一個方法的執行個體,從而實現回調。

function a(b, c, d) {    console.log("hello a");    b(c, d);};function b(c, d) {    console.log("hello b");    c(d);};function c(d) {    console.log("hello c");    d()};function d() {    console.log("hello d");};a(b, c, d);

 

輸出結果

hello ahello bhello chello d

 

如果回呼函數寫的多了,會造成代碼特別特別噁心。

如果有類似於sync的函數能讓任務順序執行就更好了。終於找到了async這個庫 $ npm instanll async

async = require("async");a = function (callback) {    // 延遲5s類比耗時操作    setTimeout(function () {        console.log("hello world a");        // 回調給下一個函數        callback(null, "function a");    }, 5000);};b = function (callback) {    // 延遲1s類比耗時操作    setTimeout(function () {        console.log("hello world b");        // 回調給下一個函數        callback(null, "function b");    }, 1000);};c = function (callback) {    console.log("hello world c");    // 回調給下一個函數    callback(null, "function c");};// 根據b, a, c這樣的順序執行async.series([b, a, c], function (error, result) {    console.log(result);});

 

注釋基本能夠很好的理解了,我們看看輸出

hello world bhello world ahello world c[ ‘function b‘, ‘function a‘, ‘function c‘ ]

 

上面的基本async模組的實現的如果瞭解更多關於async模組的使用,可以點擊:查看詳情

其實nodeJS基本api也提供了非同步實現同步的方式。基於Promise+then的實現

sleep = function (time) {    return new Promise(function () {        setTimeout(function () {            console.log("end!");        }, time);    });};console.log(sleep(3000));

 

輸出結果為:

Promise { <pending> }end!

 

可以看出來,這裡返回了Promise對象,直接輸出Promise對象的時候,會輸出該對象的狀態,只有三種:PENDING、FULFILLED、REJECTED。字面意思很好理解。也就是說Promise有可能能實現我們非同步任務同步執行的功能。我們先用Promise+then結合起來實現非同步任務同步操作。

sleep = function () {    return new Promise(function (resolve, reject) {        setTimeout(function () {            console.log("start!");            resolve();        }, 1000);    })        .then(function () {            setTimeout(function () {                console.log("end!");            }, 2000);        })        .then(function () {            console.log("end!!");        })};console.log(sleep(1000));

 

輸出結果:

Promise { <pending> }start!end!!end!

 

在new Promise任務執行完後,調用了resolve才會執行所有的then函數,並且這些then函數是非同步執行的。由輸出結果可以知道。(如果所有then是順序執行的應該是end! -> end!!)。但是上述也做到了兩個非同步任務之間順序執行了。

不過,還有更加優雅的方式:使用async+await。

display = function(time, string) {    return new Promise(function (resovle, reject) {        setTimeout(function () {            console.log(string);            resovle();        }, time)    });};// 執行順序:b a cfn = async function () {    // 會造成阻塞    await display(5000, "b");    await display(3000, "a");    await display(5000, "c");}();

 

輸出結果:

bac

 

由於這裡時間輸出比較尷尬,只能通過我們來感知,本人通過個人“感知”知道了在display b過度到display a的時候大概用了3s,再過度到display c的時候大概用了5s

NodeJS實現同步的方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.