• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答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
    主站蜘蛛池模板: 国产精品天天看天天狠| 青青草国产精品久久| 99精品国产在热久久无毒不卡| 国产精品你懂的在线播放| 国产精品综合色区在线观看| 亚洲精品国产综合久久一线| 国产精品极品| 亚洲国产精品久久久久婷婷软件| 精品福利一区二区三区免费视频| 男女男精品视频网站在线观看| 91午夜精品亚洲一区二区三区| 国产精品嫩草影院AV| 十八18禁国产精品www| 久久精品国产亚洲av瑜伽| 国产成人精品日本亚洲专区| 91精品国产自产在线观看永久| 日韩精品区一区二区三VR| 亚洲精品偷拍视频免费观看| 久久免费国产精品| 国内精品久久久久久久coent| 国产2021久久精品| 国产高清在线精品一区二区三区| 九九热这里只有在线精品视 | 中文字幕日韩精品无码内射 | 国产精品va久久久久久久| 青青青国产依人精品视频| 福利姬在线精品观看| AV无码精品一区二区三区| 国产日韩精品欧美一区| 3D动漫精品啪啪一区二区下载| 国产欧美日韩综合精品一区二区| 久久精品国产亚洲精品2020| 精品欧洲av无码一区二区| 精品无码人妻一区二区三区品 | 国产精品久久99| 国产高清在线精品一区| 精品在线免费观看| 国产高清在线精品一本大道国产| 国产精品日韩欧美在线第3页| 国产女人18毛片水真多18精品| 国产精品污WWW一区二区三区 |