[JavaScript General] XMLHttpRequest する関数を Promise を返すように修正するチュートリアルをやってみた
Promise を利用すれば、非同期処理の書き方を統一できることを学んだ。
こちらを参考にチュートリアルをやってみた。
JavaScript Promiseの本
'use strict';
require('babel-polyfill');
/**
* @param {String} URL
* @return {Promise}
*/
function getURL(URL) {
return new Promise((resolve, reject) => {
let req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function() {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function() {
reject(new Error(req.statusText));
};
req.send();
});
}
let URL = 'http://httpbin.org/get';
getURL(URL).then(function onFulfilled(value) {
console.log(value);
}).catch(function onRejected(error) {
console.error(error);
});
JavaScriptの入門書 #jsprimer
モダンな JS かつ説明が丁寧でとてもありがたい。
JS 力がなさ過ぎて onclick
で動かせなかった。
'use strict';
require('babel-polyfill');
let el = document.getElementById('btn');
el.addEventListener('click', function() {
main();
});
/**
* Main & console error.
*/
function main() {
const userId = document.getElementById('userId').value;
getUserInfo(userId)
.then((userInfo) => createView(userInfo))
.then((view) => displayView(view))
.catch((error) => {
console.error(`エラーが発生しました (${error})`);
});
}
/**
* Get User information from Github.
* @param {String} userId
* @return {Promise}
*/
function getUserInfo(userId) {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('GET', `https://api.github.com/users/${userId}`);
request.addEventListener('load', (event) => {
if (event.target.status !== 200) {
reject(new Error(`${event.target.status}: ${event.target.statusText}`));
}
const userInfo = JSON.parse(event.target.responseText);
resolve(userInfo);
});
request.addEventListener('error', () => {
reject(new Error('Network Error'));
});
request.send();
});
}
/**
* Create a view at HTML tags.
* @param {Object} userInfo
* @return {String}
*/
function createView(userInfo) {
/* eslint-disable no-unused-vars */
return escapeHTML`
<h4>${userInfo.name} (@${userInfo.login})</h4>
<img src="${userInfo.avatar_url}" alt="${userInfo.login}" height="100">
<dl>
<dt>Location</dt>
<dd>${userInfo.location}</dd>
<dt>Repositries</dt>
<dd>${userInfo.public_repos}</dd>
</dl>
`;
}
/**
* Display a view to #result in HTML.
* @param {String} view
*/
function displayView(view) {
const result = document.getElementById('result');
result.innerHTML = view;
}
/**
* Escape HTML special characters.
* @param {String} str
* @return {String}
*/
function escapeSpecialChars(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
/**
* Escape HTML tags from strings.
* @param {Strings} strings
* @return {String}
*/
function escapeHTML(strings, ...values) {
return strings.map((part, i) => {
const value = values[i];
if (value) {
if (typeof value === 'string') {
return part + escapeSpecialChars(value);
} else {
return part + String(value);
}
} else {
return part;
}
}).join('');
}
Promise のユースケース代表例の XMLHttpRequest が理解しやすかった。
XHR -> HTML組み立て -> View の流れがイメージできるようになって助かった。
他にはどんなユースケースがあるのか知りたい。
Promise のテストについては、今の理解度では足りなかったので今後の課題とする。