<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
        主站蜘蛛池模板: 亚洲精品456人成在线| 亚洲精品日韩一区二区小说| 黄色网址免费观看| 久久水蜜桃亚洲AV无码精品| 亚洲国产V高清在线观看| 久久成人无码国产免费播放| 国产成人精品亚洲2020| 亚洲国产综合久久天堂| 在线观看免费视频资源| 处破女第一次亚洲18分钟| 亚洲AV日韩AV永久无码绿巨人| 韩国免费一级成人毛片| 九九99热免费最新版| 亚洲人成综合在线播放| 亚洲精品视频在线看| 国产精品69白浆在线观看免费| 男女作爱免费网站| 亚洲人成人77777网站不卡| 不卡精品国产_亚洲人成在线| 2021免费日韩视频网| 两个人看的www免费高清| wwwxxx亚洲| 亚洲国产精品无码久久一区二区| 全免费a级毛片免费**视频| 国产免费无码一区二区| 免费看黄网站在线看| 亚洲一级毛片在线观| 亚洲人成图片小说网站| 狠狠久久永久免费观看| 日日麻批免费40分钟日本的| 成人免费一区二区三区| 美女的胸又黄又www网站免费| 亚洲综合免费视频| 国产成人精品日本亚洲网站| 亚洲国产成人久久笫一页| 久久久久免费看黄A片APP| 久久ww精品w免费人成| 免费国产午夜高清在线视频| 国产精品九九久久免费视频| 亚洲成a人无码亚洲成www牛牛| 亚洲天堂一区二区三区|