国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答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
主站蜘蛛池模板: 黄毛片 | 国产日韩中文字幕 | 日本特级淫片免费 | 国内精品伊人久久久影视 | 国产高清a毛片在线看 | 日韩不卡一区二区 | 日韩电影中文字幕在线网站 | 成人区精品一区二区毛片不卡 | 精品久久综合一区二区 | 欧美一区二区日韩一区二区 | 图片专区亚洲欧美另类 | 日韩一区二区三区在线视频 | 婷婷综合久久中文字幕蜜桃三电影 | 国产高清a毛片在线看 | 精品欧美一区二区三区在线 | 香蕉视频免费在线看 | 国产毛片一区二区三区精品 | 亚洲精品社区 | 国产一区二区三区欧美 | 国产精品一区久久 | 欧美日韩一区二区三区四区 | 精品日韩欧美一区二区三区 | 国产成人一区二区三区影院免费 | 亚洲精品午夜国产va久久成人 | 波多野结衣免费在线 | 国产有码视频 | a级毛片在线播放 | 日韩最新视频一区二区三 | 在线观看国产欧美 | 欧洲亚洲欧美国产日本高清 | 亚洲免费网站观看视频 | 色综合色狠狠天天综合色 | 情趣视频网站 | 国产精品电影一区二区三区 | 成人日韩在线 | 亚洲高清视频在线 | 国产高清a毛片在线看 | 国产高清精品久久久久久久 | 国产精品ⅴ视频免费观看 | 香蕉国产精品 | 欧美国产成人精品一区二区三区 |