Promise 使ってみる
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ 私としては コールバックでも別にいいかな
今度は使ってみるです
XHR とそれを使って Mime type を取得するものです
元
Promise 化
Promise のほうが Promise のコンストラクタに渡す関数にする分 ネストが多いです
コールバック渡す方法でも気をつければそこまでコールバック地獄にならないですし 個人的には Promise なくても困らないといえば困らないかなー と思います
使う側になると Promise のほうが書く量が少ないです
それに コールバックを渡さないので 普通の関数の return みたいに返り値を使って書けます
やっぱり私としてはどっちでもいいかなー
さすがにコールバックでこんなコードを書かれたら Promise のほうがいいと思いますけど
ダメなやつ
Promise を返す関数を作る
昔作ってたライブラリの一部を Promise 化してみますXHR とそれを使って Mime type を取得するものです
元
function getActualMimeType(url, cb){
XHR(url, "HEAD", xhr => {
cb(xhr.status === 200 ? xhr.getResponseHeader("Content-Type") : null)
}, xhr => {
cb(null)
})
}
function XHR(url, type, headers, cb, cberr){
var xhr = new XMLHttpRequest()
xhr.open(type, url)
xhr.onload = function(){
if(this.readyState == 4){
cb(this);
}
}
xhr.onerror = cberr || function(){}
xhr.ontimeout = cberr || function(){}
if(type.toUpperCase() === "POST"){
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}
headers && headers.forEach((val, key) => xhr.setRequestHeader(key, val))
xhr.send()
}
XHR(url, "HEAD", xhr => {
cb(xhr.status === 200 ? xhr.getResponseHeader("Content-Type") : null)
}, xhr => {
cb(null)
})
}
function XHR(url, type, headers, cb, cberr){
var xhr = new XMLHttpRequest()
xhr.open(type, url)
xhr.onload = function(){
if(this.readyState == 4){
cb(this);
}
}
xhr.onerror = cberr || function(){}
xhr.ontimeout = cberr || function(){}
if(type.toUpperCase() === "POST"){
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}
headers && headers.forEach((val, key) => xhr.setRequestHeader(key, val))
xhr.send()
}
Promise 化
function getActualMimeType(url){
return new Promise((success, fail) => {
XHR(url, "HEAD").then(xhr => {
if(xhr.status === 200)
success(xhr.getResponseHeader("Content-Type"))
else
return Promise.reject()
}).catch(xhr => {
fail(null)
})
})
}
function XHR(url, type, headers){
return new Promise((success, fail) => {
var xhr = new XMLHttpRequest()
xhr.open(type, url)
xhr.onload = function(){
if(this.readyState == 4){
success(this);
}
}
xhr.onerror = fail
xhr.ontimeout = fail
if(type.toUpperCase() === "POST"){
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}
headers && headers.forEach((val, key) => xhr.setRequestHeader(key, val))
xhr.send()
})
}
return new Promise((success, fail) => {
XHR(url, "HEAD").then(xhr => {
if(xhr.status === 200)
success(xhr.getResponseHeader("Content-Type"))
else
return Promise.reject()
}).catch(xhr => {
fail(null)
})
})
}
function XHR(url, type, headers){
return new Promise((success, fail) => {
var xhr = new XMLHttpRequest()
xhr.open(type, url)
xhr.onload = function(){
if(this.readyState == 4){
success(this);
}
}
xhr.onerror = fail
xhr.ontimeout = fail
if(type.toUpperCase() === "POST"){
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}
headers && headers.forEach((val, key) => xhr.setRequestHeader(key, val))
xhr.send()
})
}
Promise のほうが Promise のコンストラクタに渡す関数にする分 ネストが多いです
コールバック渡す方法でも気をつければそこまでコールバック地獄にならないですし 個人的には Promise なくても困らないといえば困らないかなー と思います
Promise を返す関数を使う
それぞれで /1, /2, /3 に順番にアクセスして終わったら end と表示するコードを書いてみるとこうなりますfunction fn_callback(cb){
start()
function start(){
XHR("/1", "GET", {}, after1, error)
}
function after1(xhr){
XHR("/2", "GET", {}, after2, error)
}
function after2(xhr){
XHR("/3", "GET", {}, cb, error)
}
function error(e){
console.log(e)
cb()
}
}
fn_callback(_ => console.log("end"))
function fn_promise(){
return XHR("/1", "GET", {})
.then(xhr => {
return XHR("/2", "GET", {})
})
.then(xhr => {
return XHR("/3", "GET", {})
})
.catch(e => console.log(e))
}
fn_promise().then(_ => console.log("end"))
start()
function start(){
XHR("/1", "GET", {}, after1, error)
}
function after1(xhr){
XHR("/2", "GET", {}, after2, error)
}
function after2(xhr){
XHR("/3", "GET", {}, cb, error)
}
function error(e){
console.log(e)
cb()
}
}
fn_callback(_ => console.log("end"))
function fn_promise(){
return XHR("/1", "GET", {})
.then(xhr => {
return XHR("/2", "GET", {})
})
.then(xhr => {
return XHR("/3", "GET", {})
})
.catch(e => console.log(e))
}
fn_promise().then(_ => console.log("end"))
使う側になると Promise のほうが書く量が少ないです
それに コールバックを渡さないので 普通の関数の return みたいに返り値を使って書けます
やっぱり私としてはどっちでもいいかなー
さすがにコールバックでこんなコードを書かれたら Promise のほうがいいと思いますけど
ダメなやつ
function fn_callback(cb){
XHR("/1", "GET", {}, function(xhr){
XHR("/2", "GET", {}, function(xhr){
XHR("/3", "GET", {}, cb, function(e){
console.log(e)
cb()
})
}, function(e){
console.log(e)
cb()
})
}, function(e){
console.log(e)
cb()
})
}
fn_callback(_ => console.log("end"))
XHR("/1", "GET", {}, function(xhr){
XHR("/2", "GET", {}, function(xhr){
XHR("/3", "GET", {}, cb, function(e){
console.log(e)
cb()
})
}, function(e){
console.log(e)
cb()
})
}, function(e){
console.log(e)
cb()
})
}
fn_callback(_ => console.log("end"))
Object に forEach メソッドを作ってないとエラー出ますのでコピペの際は注意してください