<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        Node.js異步編程之Callback介紹(一)_node.js

        來源:懂視網 責編:小采 時間:2020-11-27 21:36:18
        文檔

        Node.js異步編程之Callback介紹(一)_node.js

        Node.js異步編程之Callback介紹(一)_node.js:Node.js 基于 JavaScript 引擎 v8,是單線程的。Node.js 采用了與通常 Web 上的 JavaScript 異步編程的方式來處理會造成阻塞的I/O操作。在 Node.js 中讀取文件、訪問數據庫、網絡請求等等都有可能是異步的。對于 Node.js 新人或者從其他語言背景遷移
        推薦度:
        導讀Node.js異步編程之Callback介紹(一)_node.js:Node.js 基于 JavaScript 引擎 v8,是單線程的。Node.js 采用了與通常 Web 上的 JavaScript 異步編程的方式來處理會造成阻塞的I/O操作。在 Node.js 中讀取文件、訪問數據庫、網絡請求等等都有可能是異步的。對于 Node.js 新人或者從其他語言背景遷移

        Node.js 基于 JavaScript 引擎 v8,是單線程的。Node.js 采用了與通常 Web 上的 JavaScript 異步編程的方式來處理會造成阻塞的I/O操作。在 Node.js 中讀取文件、訪問數據庫、網絡請求等等都有可能是異步的。對于 Node.js 新人或者從其他語言背景遷移到 Node.js 上的開發者來說,異步編程是比較痛苦的一部分。本章將由淺入深為大家講解 Node.js 異步編程的方方面面。從最基礎的 callback 到 thunk、Promise、co 直到 ES7 計劃的 async/await。

        首先我們先從一個具體的異步編程的例子說起。

        獲取多個 ip 所在地的天氣信息

        在 ip.json 這個文件中,有一個數組我們存放了若干個 ip 地址,分別來自不同的地方的不同訪問者,內容如下:
        代碼如下:
        // ip.json
        ["115.29.230.208", "180.153.132.38", "74.125.235.224", "91.239.201.98", "60.28.215.115"]

        希望可以每一個 ip 所在地當前的天氣。將結果輸出到 weather.json 這個文件中各式如下:
        代碼如下:
        // weather.json
        [
        { "ip": "115.29.230.208", "weather": "Clouds", "region": "Zhejiang" },
        { "ip": "180.153.132.38", "weather": "Clear", "region": "Shanghai" },
        { "ip": "74.125.235.224", "weather": "Rain", "region": "California" },
        { "ip": "60.28.215.115", "weather": "Clear", "region": "Tianjin" }
        ]

        整理思路,我們分成以下幾步來完成:

        1.讀取 ip 地址;
        2.根據 ip 地址獲取 ip 所在地的地理位置;
        3.根據地理位置查詢當地的天氣;
        4.將結果寫入到 weather.json 文件中。

        這些步驟都是異步的(讀寫文件可以同步,但作為示例,都用異步)。

        callback

        首先我們嘗試不借助任何庫,試著以 Node.js API 通常提供的方式——專遞一個 callback 作為異步回調——來實現。我們將借助三個基礎模塊:

        1.fs:從文件 ip.json 讀取 IP 列表;把結果寫入到文件中;
        2.request:用來發送 HTTP 請求,根據 IP 地址獲取 geo 數據,再通過 geo 數據獲取天氣數據;
        3.querystring:用來組裝發送請求的 url 參數。

        新建一個 callback.js 文件,引入這幾個模塊:
        代碼如下:
        // callback.js
        var fs = require('fs')
        var request = require('request')
        var qs = require('querystring')

        讀取文件中的 IP 列表,調用 fs.readFile 讀取文件內容,再通過 JSON.parse 來解析 JSON 數據:
        代碼如下:
        ...
        function readIP(path, callback) {
        fs.readFile(path, function(err, data) {
        if (err) {
        callback(err)
        } else {
        try {
        data = JSON.parse(data)
        callback(null, data)
        } catch (error) {
        callback(error)
        }
        }
        })
        }
        ...

        接著就是使用 IP 來獲取geo,我們使用 request 來請求一個開放的 geo 服務:
        代碼如下:
        ...
        function ip2geo(ip, callback) {
        var url = 'http://www.telize.com/geoip/' + ip
        request({
        url: url,
        json: true
        }, function(err, resp, body) {
        callback(err, body)
        })
        }
        ...

        使用 geo 數據來獲取 weather:
        代碼如下:
        ...
        function geo2weather(lat, lon, callback) {
        var params = {
        lat: lat,
        lon: lon,
        APPID: '9bf4d2b07c7ddeb780c5b32e636c679d'
        }
        var url = 'http://api.openweathermap.org/data/2.5/weather?' + qs.stringify(params)
        request({
        url: url,
        json: true,
        }, function(err, resp, body) {
        callback(err, body)
        })
        }
        ...

        現在我們已經獲取 geo、獲取 weather 的接口,接下來我們還有稍微復雜的問題要處理,因為 ip 有多個,所以我們需要并行地去讀取 geo 已經并行地讀取 weather 數據:
        代碼如下:
        ...
        function ips2geos(ips, callback) {
        var geos = []
        var ip
        var remain = ips.length
        for (var i = 0; i < ips.length; i++) {
        ip = ips[i];
        (function(ip) {
        ip2geo(ip, function(err, geo) {
        if (err) {
        callback(err)
        } else {
        geo.ip = ip
        geos.push(geo)
        remain--
        }
        if (remain == 0) {
        callback(null, geos)
        }
        })
        })(ip)
        }
        }

        function geos2weathers(geos, callback) {
        var weathers = []
        var geo
        var remain = geos.length
        for (var i = 0; i < geos.length; i++) {
        geo = geos[i];
        (function(geo) {
        geo2weather(geo.latitude, geo.longitude, function(err, weather) {
        if (err) {
        callback(err)
        } else {
        weather.geo = geo
        weathers.push(weather)
        remain--
        }
        if (remain == 0) {
        callback(null, weathers)
        }
        })
        })(geo)
        }
        }
        ...

        ips2geos 和 geos2weathers 都使用了一種比較原始的方法,remain 來計算等待返回的個數,remain 為 0 表示并行請求結束,將處理結果裝進一個數組返回。

        最后就是將結果寫入到 weather.json 文件中:
        代碼如下:
        ...
        function writeWeather(weathers, callback) {
        var output = []
        var weather
        for (var i = 0; i < weathers.length; i++) {
        weather = weathers[i]
        output.push({
        ip: weather.geo.ip,
        weather: weather.weather[0].main,
        region: weather.geo.region
        })
        }
        fs.writeFile('./weather.json', JSON.stringify(output, null, ' '), callback)
        }
        ...

        組合上面這些函數,我們就可以實現我們的目標:
        代碼如下:
        ...
        function handlerError(err) {
        console.log('error: ' + err)
        }

        readIP('./ip.json', function(err, ips) {
        if (err) {
        handlerError(err)
        } else {
        ips2geos(ips, function(err, geos) {
        if (err) {
        handlerError(err)
        } else {
        geos2weathers(geos, function(err, weathers) {
        if (err) {
        handlerError(err)
        } else {
        writeWeather(weathers, function(err) {
        if (err) {
        handlerError(err)
        } else {
        console.log('success!')
        }
        })
        }
        })
        }
        })
        }
        })

        哈哈,你媽這嵌套,你可能覺得這就是 JavaScript 異步的問題,說真的,嵌套不是 JavaScript 異步的真正問題所在。上面這段代碼我們可以下面這樣寫:
        代碼如下:
        ...
        function ReadIPCallback(err, ips) {
        if (err) {
        handlerError(err)
        } else {
        ips2geos(ips, ips2geosCallback)
        }
        }

        function ips2geosCallback(err, geos) {
        if (err) {
        handlerError(err)
        } else {
        geos2weathers(geos, geos2weathersCallback)
        }
        }

        function geos2weathersCallback(err, weathers) {
        if (err) {
        handlerError(err)
        } else {
        writeWeather(weathers, writeWeatherCallback)
        }
        }

        function writeWeatherCallback(err) {
        if (err) {
        handlerError(err)
        } else {
        console.log('success!')
        }
        }

        readIP('./ip.json', ReadIPCallback)

        好了,這是我們 callback.js 的全部內容。運行:
        代碼如下:
        node callback.js

        將會生成 weater.json 文件:
        代碼如下:
        [
        {
        "ip": "180.153.132.38",
        "weather": "Clear",
        "region": "Shanghai"
        },
        {
        "ip": "91.239.201.98",
        "weather": "Clouds"
        },
        {
        "ip": "60.28.215.115",
        "weather": "Clear",
        "region": "Tianjin"
        },
        {
        "ip": "74.125.235.224",
        "weather": "Clouds",
        "region": "California"
        },
        {
        "ip": "115.29.230.208",
        "weather": "Clear",
        "region": "Zhejiang"
        }
        ]

        那正真的問題是什么?

        當然是異步的問題啦,異步本質上要處理三個事情:

        1.異步操作什么時候結束,需要通知回來,Callback 是一種方案;
        2.異步產生的結果需要傳遞回來,Callback 接受一個 data 參數,把數據傳回來;
        3.異步如果出錯了怎么辦?Callback 接受 一個 err 參數,把錯誤傳回來。

        但有沒有發現好多重復的工作(各種 callback)?上面的這些代碼有什么問題么?請大家期待本文的續篇。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Node.js異步編程之Callback介紹(一)_node.js

        Node.js異步編程之Callback介紹(一)_node.js:Node.js 基于 JavaScript 引擎 v8,是單線程的。Node.js 采用了與通常 Web 上的 JavaScript 異步編程的方式來處理會造成阻塞的I/O操作。在 Node.js 中讀取文件、訪問數據庫、網絡請求等等都有可能是異步的。對于 Node.js 新人或者從其他語言背景遷移
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 中字幕视频在线永久在线观看免费| 一级做受视频免费是看美女| 91精品免费观看| 亚洲国产精品第一区二区| 13小箩利洗澡无码视频网站免费| 国产亚洲精品AA片在线观看不加载 | 亚洲欧洲另类春色校园小说| 2015日韩永久免费视频播放| 亚洲日本视频在线观看| 99视频全部免费精品全部四虎| 亚洲AV成人无码天堂| 无码国模国产在线观看免费| 国产产在线精品亚洲AAVV| 亚洲第一区在线观看| 中文字幕a∨在线乱码免费看| 久久久青草青青亚洲国产免观| 国产精品免费大片| 精品亚洲AV无码一区二区| 国产色婷婷精品免费视频| 特黄特色的大片观看免费视频| 国产美女亚洲精品久久久综合| 久久一本岛在免费线观看2020| 亚洲三级在线观看| 亚洲AV中文无码乱人伦| 免费久久人人爽人人爽av| 亚洲国产美女在线观看| 日韩中文无码有码免费视频| 国产美女视频免费观看的网站| 激情内射亚洲一区二区三区| 成人免费在线视频| 精品免费久久久久国产一区| 亚洲成人午夜电影| 午夜亚洲国产成人不卡在线| 最新国产乱人伦偷精品免费网站 | 亚洲AV日韩综合一区| 国产精品亚洲综合一区| 日本高清在线免费| 国产精品免费视频观看拍拍| 亚洲成人网在线观看| 亚洲精品线路一在线观看| 6080午夜一级毛片免费看|