IMUZA.com

Xserver<<WordPress(ConoHa)<<はてなブログ

ホーム / javascript / 非同期処理を Promise と then で書き直す

非同期処理を Promise と then で書き直す

2019/03/26 javascript, はてなブログ

下記前記事を Promise と then を使って書き直しました。

www.imuza.com

Promise

Promise – JavaScript | MDN

とりあえずは非同期処理のコールバック関数に変わるものという理解でいいかと思いますが、promise の意味からしますと、今はまだ結果を返せないけれどもいつか終わったら返しますよと約束するオブジェクトみたいなことでしょうか。

上の MDN のページに XMLHttpRequest を使ったサンプルコードがありましたのでそのまま使ってみることにします。

function getFile(url, method) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open(method || 'GET', url, true);
        xhr.onload = () => resolve(xhr.responseText);
        xhr.onerror = () => reject(xhr.statusText);
        xhr.send();
    });
}

アロー関数で書かれています。url を渡し、非同期でファイル取得に成功した場合は、resolve で返し、失敗した場合は、reject で返すということですね。

then

Promise.prototype.then() – JavaScript | MDN

で、getFile関数の戻り値を then で受ければコールバック関数として働くということになるんでしょうか。

getFile(url)
    .then((file) => createBlogcard(file, embed, url)) // 取得したファイルからブログカードを作る関数
    .then((card) => iframe.parentNode.replaceChild(card, iframe)) // ブログカードをiframe と入れ替える
    .catch((error) => console.error(`error`));

メソッドチェーンにしてみましたけど、

getFile(url)
    .then((file) => {
        var card = createBlogcard(file, embed, url);
        iframe.parentNode.replaceChild(card, iframe);
    })
    .catch((error) => {
        console.error(`error`);
    });

これでも同じですね。

Promise に書き換えた div版ブログカード

ということで、前記事を Promise と then を使って書き直しました。

(function(){
function getFile(url, method) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method || 'GET', url, true);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
function createBlogcard(file, embed, url) {
const parser = new DOMParser();
var doc = parser.parseFromString(file, 'text/html');
if(embed){ // 記事ページの場合
var blogcard = doc.getElementsByClassName('embed-wrapper')[0];
var times = blogcard.getElementsByTagName('time');
if(times !== undefined) times[0].removeAttribute('data-relative');
var links = blogcard.getElementsByTagName('a');
Array.prototype.forEach.call(links, function(link){
link.setAttribute('target', '_top');
});
}else{ // 検索ページやアーカイブページの場合
var meta = doc.getElementsByTagName('meta');
var og = {};
var re = /og:(.+)/;
for(var i=0; i<meta.length; i++){
var p = meta[i].getAttribute('property');
if(p !== null){
var matches = p.match(re);
if(matches !== null){
og[matches[1]] = meta[i].getAttribute('content');
}
}
}
var re = /(.+) - .+/;
og.title = og.title.match(re)[1];
og.site_url = url.split('/')[2];
og.description = og.description.substr(0, 100) + '...';
var blogcard = document.createElement('div');
blogcard.classList.add('embed-wrapper');
blogcard.innerHTML = '<div class="embed-wrapper-inner"><div class="embed-content with-thumb"><div class="thumb-wrapper">'
+ '<a href="' + url + '" target="_top">'
+ '<img src="' + og.image + '" class="thumb"></a></div><div class="entry-body"><h2 class="entry-title">'
+ '<a href="' + url + '" target="_top">' + og.title + '</a></h2>'
+ '<div class="entry-content">' + og.description + '</div></div></div><div class="embed-footer">'
+ '<a href="' + url + '" target="_top">'
+ '<img src="https://cdn-ak.favicon.st-hatena.com?url=' + url + '" alt="' + og.site_name + '" title="' + og.site_name + '" class="favicon">' + og.site_name + '</a>'
+ '<img src="https://s.st-hatena.com/entry.count.image?uri=' + url + '" alt="" class="star-count">'
+ '<a href="http://b.hatena.ne.jp/entry/' + url + '" target="_top">'
+ '<img src="https://b.hatena.ne.jp/entry/image/' + url + '" class="bookmark-count"></a></div>';
}
return blogcard;
}
var article = document.getElementsByTagName('article')[0];
if(article !== undefined){
var iframes = article.getElementsByTagName('iframe');
var reg = new RegExp('http(s)?%3A%2F%2F' + location.hostname + '.+$');
Array.prototype.forEach.call(iframes, function(iframe){
var embedUrl = reg.exec(iframe.src);
if(embedUrl !== null){
iframe.src = '';
if(embedUrl[0].indexOf('entry') !== -1){
var url = decodeURIComponent(embedUrl[0]).replace('entry', 'embed');
var embed = true;
}else{
var url = decodeURIComponent(embedUrl[0]);
var embed = false;
}
getFile(url)
.then((file) => createBlogcard(file, embed, url))
.then((card) => iframe.parentNode.replaceChild(card, iframe))
.catch((error) => console.error(`error`));
}
});
}
})();

記事ページの場合は、embed 差し替えて呼べばブログカードを取得できますが、たとえば検索ページやアーカイブページの場合は単なるリンクのカードになりますので、その場合は OGPデータからカードを作っています。

CSS ははてなブログカードの iframe を div に差し替える(自サイトのみ)」と同じです。

まだまだ javascript 初級者から脱しきれません(涙)。

はてなブログカードの iframe を div に差し替える(自サイトのみ)
はてなブログ用 Javascriptモジュール imzModules ver.2.0
Twitter
Facebook
ブックマーク
LINEで送る

最初のサイドバー

最新記事

2023/02/1

WordPress:期間指定で人気記事を表示(プラグインなし)

2023/01/26

WordPress:メニューのid,classを整理カスタマイズ

2023/01/19

WordPress:JSON-LD構造化データをプラグインなしで出力

2023/01/11

WordPress:OGPタグをプラグインなしで挿入する

2022/12/27

WordPress:canonicalタグをプラグインなしで制御する

最新記事を一覧で見る

よく読まれている記事

よく読まれている記事を一覧で見る

カテゴリー

  • はてなブログ214
  • WebTips108
  • javascript98
  • Joomla!88
  • Windows68
  • CSS63
  • Wordpress60
  • Joomla!更新53
  • Linux49
  • はてなテーマ45
  • Plamo33
  • Google32
  • はてなプラグイン25
  • php22
  • Node.js18
  • Ubuntu16
  • SASS16
  • laravel415
  • Chrome11
  • cms-style10
  • iPhone9
  • genesis6
  • ConoHa WING6
  • Git入門6
  • Python5
  • Android5
  • スマートフォン4
  • PC全般4
  • 静的サイトジェネレーター3
  • Firefox3
  • SSD3
  • Facebook3
  • Blankslate3
  • Docker3
  • Mactype2
  • GitHub2
  • youtube1
  • rails入門1
  • Twitter1
  • はてなブクマ1
  • 映画1
  • Xserver1

Footer

My Web Sites

  • @半径とことこ60分
  • そんなには褒めないよ。映画評
  • IMUZA.com
  • GitHub

Related Sites

  • WordPress公式
  • WordPress関数リファレンス
  • PHPマニュアル

Contact Us

  • お問い合わせフォーム
  • Twitter
  • Facebook
  • Feedly

Copyright © 2023 · IMUZA.com