Asa Tech Blog

学んだことを備忘録として残しています

Promise.allとPromise.allSettledの違い

大量のメール送信処理などで、非同期処理を複数実行する必要がある場合に、効率的に並列で実行できるメソッドとしてPromise.all()があります。 Promise.allを使う中で、もしかして、途中で失敗する非同期処理があったら、すべて処理が実行されなくなるのではと疑問に思ったので、Promise.allの挙動を調べることにしました。

Promise.all

Promise.allは、MDNでは以下のように説明されています。

Promise.all() メソッドは入力としてプロミスの集合の反復可能オブジェクトを取り、入力したプロミスの集合の結果の配列に解決される単一の Promise を返します。この返却されたプロミスは、入力したプロミスがすべて解決されるか、入力した反復可能オブジェクトにプロミスが含まれていない場合に解決されます。入力したプロミスのいずれかが拒否されるか、プロミス以外のものがエラーを発生させると直ちに拒否され、最初に拒否されたメッセージまたはエラーをもって拒否されます。 Promise.all() - JavaScript | MDN

var p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('one'), 1000);
});
var p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('two'), 2000);
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('three'), 3000);
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('four'), 4000);
});
var p5 = new Promise((resolve, reject) => {
  reject(new Error('reject'));
});

// Using .catch:
Promise.all([p1, p2, p3, p4, p5])
.then(values => {
  console.log(values);
})
.catch(error => {
  console.error(error.message)
});

//From console:
//"reject"

Promise.all() では、複数あるPromiseの実行が1つでもrejectを返すと、Promise.all は直ちに拒否されるようです。

Promise.allSettled

Promise.allSettled() メソッドは、与えられたすべてのプロミスが履行されたか拒否された後に、それぞれのプロミスの結果を記述した配列オブジェクトで解決されるプロミスを返します。

Promise.allSettled([
  Promise.resolve(33),
  new Promise(resolve => setTimeout(() => resolve(66), 0)),
  99,
  Promise.reject(new Error('an error'))
])
.then(values => console.log(values));

// [
//   {status: "fulfilled", value: 33},
//   {status: "fulfilled", value: 66},
//   {status: "fulfilled", value: 99},
//   {status: "rejected",  reason: Error: an error}
// ]

Promise.allSettledでは、Promiseがrejectされてもそのまま処理が続くようです。

まとめ

Promiseが失敗しても、処理を続けたいという場合は、Promise.allSettledを使ったほうが良さそうです

なぜReact propsをスプレッド演算子で渡すことができるのか?

通常、JSXでComponentにprops を渡す場合、下のように書ける。

const props = { hoge: 'aaa', fuga: 'bbb' }

<Component hoge={props.hoge} fuga={props.huga} />

スプレッド演算子を用いると、より簡潔に書き換えられます.

const props = {hoge: 'aaa', fuga: 'bbb' }
<Component {...props} />

僕は、スプレッド演算子の書き方でReact propsを渡せることに違和感がありました。そのため、なぜReact propsをスプレッド演算子で渡すことができるのか調査しました。

JSXとReact.createElementの関係

公式ドキュメントによれば、JSX とは、つまるところ React.createElement(component, props, ...children) の糖衣構文にすぎないそうです。 JSXで書いたコードは、React.createElementにコンパイルされます。

JSX

<MyButton color="blue" shadowSize={2}>
  Click Me
</MyButton>


React.createElement(
  MyButton,
  {color: 'blue', shadowSize: 2},
  'Click Me'
)

createElement()の第1引数は、タグ名の文字列('div' や 'span' など)、React component 型(クラスもしくは関数)、React fragment 型のいずれか、第2引数は、各propsをまとめてObject化したもの 第3引数は、タグの子要素が入ります

スプレッド構文利用パターンだと下のようになります。React.createElementへのコンパイルをイメージすればなぜreact propsをスプレッド演算子で渡すことができるのか理解できました。

JSX

<MyButton {...props}>
  Click Me
</MyButton>


React.createElement(
  MyButton,
  {..props},
  'Click Me'
)

参考:

ja.reactjs.org

Reactコンポーネントでのスプレッド構文はよくよく考えたら気持ち悪くなかった - Qiita

ブロックチェーンの特徴

①自律分散システム

複数のノードが、同じデータを互いにコピーしあって同じ仕事をしているので、いくつかのロードが故障しても支障がない。

 

②管理者不在でも動く

「取引を受けつける窓口」や「各ノードに仕事を指示する管理者」といった決まった役割は存在しないので、すべてのノードが同じ役割で同じ仕事をする。したがって「ここが壊れたら一巻の終わり」という単一弱点が存在しない。

 

③ウォレットアドレス

ブロックチェーンでは公開鍵暗号の「公開鍵」と「秘密鍵」のペアキーがウォレットアドレスに対応している。ウォレットアドレスは複数作ることができる。

 

トランザクション

ブロックチェーンは「ウォレットアドレスの現在の残高」を知らない。知っているのは「過去のトランザクション(取引)」のすべての履歴。現在の残高が知りたいなら、ユーザーが、ウォレットアドレスを用いて取引履歴をすべて合算すればわかる。

 

 

参考:杉井靖典. いちばんやさしいブロックチェーンの教本 人気講師が教えるビットコインを支える仕組み 

ブロックチェーンとは

Web3のビジョンに興味を持ったので、ブロックチェーンの勉強をし始めました!

まずは、「いちばんやさしいブロックチェーンの教本」という本を読んで勉強しています。

 

ブロックチェーンの解説

ブロックチェーンを解説するのは、難しいらしい。

なぜなら、ブロックチェーンは、暗号・データ構造・P2P通信・分散システム・分散合意など、それぞれの要素が相互に関係し、たった1つの目的である「取引帳簿の革命」をなす複雑系の話をする必要があるからである。

 

ただブロックチェーンをかんたんに説明すると、

「正しい記録しかできない、変更できない、消せない、改ざんできない、壊れても自動修復される、落ちない、みんなに合意された情報だけが有効と認識される、ネットワーク共有型のデータベース」である。

 

ブロックチェーンの定義

日本ブロックチェーン協会JBA)では以下のようにブロックチェーンの定義がされている。

①「ビザンチン障害を含む不特定多数のノードを用い、時間の経過とともにその時点の合意が覆る確率が0へ収束するプロトコル、またはその実装をブロックチェーンと呼ぶ。」

 

②「電子署名とハッシュポインタを使用し改竄検出が容易なデータ構造を持ち、且つ、当該データをネットワーク上に分散する多数のノードに保持させることで、高可用性及びデータ同一性等を実現する技術を広義のブロックチェーンと呼ぶ。」

 

①を噛み砕いて説明すると、「故障を起こして正常に動作していない参加者・嘘をついている参加者がいる環境でも合意を得られる仕組みをブロックチェーンと呼ぶ」ということです。

 

ブロックチェーン技術と分散型台帳技術との関係

ブロックチェーン技術は分散型台帳技術の一種である。

 

ブロックチェーンとデータベースの違い

ブロックチェーンは、情報の記録媒体という意味では、データベースの一種である。

ただし従来のデータベースと決定的に異なることは以下のような機能をすべて備えているところにある。

 

  •  データは複数の参加者に確認されルールに従った書式のものだけが記録されること
  • 参加者全員によって合意されたデータだけが有効となる約束で運用されていること

  • 耐改ざん性のあるデータ構造(ハッシュチェーン構造)を持っていること

  • 改ざんしようとすると即時検出され、そのデータが破損していると認識されること

  • 破損データは正常なデータを持つほかの参加者から取り寄せて自動復旧できること

  • 一度書き込まれたデータは変更も削除も誰にもいっさいできないこと

  • システム全体を止めることは誰にも不可能なこと

     

 

 

 

参考:杉井靖典. いちばんやさしいブロックチェーンの教本 人気講師が教えるビットコインを支える仕組み

即時関数とは?

即時関数とは

即時関数とは、英語で IIFE (Immediately Invoked Function Expression)と呼ばれる即時実行関数式です。

即時関数は定義すると即時に実行されます。

このため、即時関数とよばれます。

即時関数を利用することで、関数を定義するだけで即実行する事ができます。

また、ブロック内からのホイスト回避や、グローバルスコープ名の汚染回避などが可能となります。

ホイストとは

ホイストとは、関数の最初に関数内ローカル変数が宣言されることです。

即時関数の例

<script>
  var sum = (function (a,b){
    var result = a + b;
    return result;
  })(1,2);
  console.log(sum);
</script>

【カンニング防止】Runteq生のブログが検索結果に表示されなくなる方法

はじめに

基礎編以降のRunteqの課題はわからないことだらけなので、Googleで検索しまくると思います。

検索していると、Runteqの先輩方が書いたブログを見つけることがあります。

僕はRunteqの先輩のブログだと気づかずに、うっかり読んでしまうこともあれば、自制心が弱いため故意にカンニングしてしまうという経験がありました。

そんな経験があったので、Runteqの先輩達のブログが検索結果に表示されないようにする方法ないかなと調べていると、いい方法が見つかったのでシェアしよう思います!

その方法は、「uBlacklistの購読機能を利用する」というものです!

uBlacklistとは

uBlacklist」は、Chrome 拡張機能の一つで、Googleの検索結果に指定したサイトを表示しないようにすることができます。

「uBlacklist」にはオプション機能として「リスト購読」があります。 「リスト購読」とは、指定した URL から定期的にリストをダウンロードして、検索結果に反映させることができる機能のことです。

この機能が利用できると思ったので、Runteqの先輩方が書いたブログのリストを作成しました!

作成したリストについて

Runteq生であろう方が、課題に少しでも関連したことを書いているブログを見つけてきて、リストにしgithubで公開しました。このリストは、マッチパターンというもので書いています。

https://raw.githubusercontent.com/arias-hooks/runteq-blog-list/master/list.txt

リストに記載するURLを追加する方法

リストに記載するURLを追加する方法は、下にあるGithubリポジトリをForkしてリストを編集してもらい、プルリクエストを送ってもらう方法がいいのかなって思ってます。直接僕のslackに、追加したいurlを送ってもらう方法でもオッケーです!

GitHub - arias-hooks/runteq-blog-list

uBlacklistでリスト購読する方法

ここからはuBlacklistのリスト購読機能を利用して、Runteqの先輩方が書いたブログを検索結果に表示されなくなる方法を説明していきます!

あまり詳しくは説明しないので、uBlacklistの詳しい使い方が知りたい方はuBlacklist開発者様のqiitaをご覧ください。

Personal Blocklist の代替になりそうな Chrome 拡張機能を作ってみた - Qiita

1. uBlacklistをChromeに追加する

uBlacklistのChromeウェブストアのページへアクセスし、uBlacklistをChromeに追加してください。

uBlacklist - Chrome ウェブストア

f:id:koshiro54600:20210303012039p:plain

2. uBlacklistのオプション画面を表示する

右上にあるツールバーの uBlacklist のアイコンをクリックして「オプション」を選び、オプションページを開いてください。

f:id:koshiro54600:20210303012329p:plain

f:id:koshiro54600:20210303012433p:plain

3. 購読を追加する

一番下にある購読の項目より「購読を追加する」ボタンをクリックします。

f:id:koshiro54600:20210303012607p:plain

名前には任意の名前をつけ、URL欄に下のURLをコピペし追加してください。

https://raw.githubusercontent.com/arias-hooks/runteq-blog-list/master/list.txt

f:id:koshiro54600:20210303012933p:plain

これでRunteqの先輩方が書いたブログを検索結果に表示されなくなったはずです!

本当に表示されなくなったか確認する

適当なキーワードで検索して、本当に表示されなくなったか確認してみます!

f:id:koshiro54600:20210303084455p:plain

このように、Runteqの先輩方が書いたブログがヒットすると、 「uBlacklist により 1 サイトがブロックされました」と表示され、ブロックされるようになりました!

「uBlacklist により 1 サイトがブロックされました」の右にある「表示する」リンクをクリックすると、ブロックしたサイトが赤色の背景で表示されます。

この機能を使えば、先輩のブログのリンクを保存しておき、課題が終わった後、確認するといったことができます!Pocketというサービスで簡単にリンクを保存できるので調べてみてください!

f:id:koshiro54600:20210303085802p:plain

「表示する」リンクを表示しない方法

「表示する」リンクがあったら、表示してカンニングしたくなっちゃうよっていう人もいるかもしれません。

そういう人のために、「表示する」リンクを表示しない方法があります!

uBlacklistオプション画面の一般項目の下に、ブロックしたサイトの数と「表示する」リンクを表示するかどうかを切り替えられるようになっているので、これをオンにすると表示されなくなります。

f:id:koshiro54600:20210303090817p:plain

uBlacklistの削除方法

Runteqの課題がすべて終わり、ポートフォリオの作成に入ったタイミングぐらいでuBlacklistを削除したらいいと思います!

Runteq生のブログはわかりやすいので、ポートフォリオの作成中に助けられることがあるかもしれません。

右上にあるツールバーのuBlacklist のアイコンを右クリックをし、「Chromeから削除」を選択すると削除できます。

f:id:koshiro54600:20210303153904p:plain

さいごに

Runteqの先輩方のブログは、すごくわかりやすくまとまっているので、非常に助かっています!!!

しかし、課題に取り組んでいるときにブログを見てしまうと、自分の頭で実装方法を考えずに課題が解けてしまうので、自走力が身につきません。自走力を身につけるために、カンニングはできるだけしないようにしていきたいですね!

Rspec勉強まとめ

  • sequenceの第二引数で定義した文字にはループの度にString#nextを末尾の文字に実行する
# 上と下は同じ
sequence(:title) { |n| "title_#{n}" }
sequence(:title, "title_1")
  • unique制約のあるカラムはsequenceを設定

  • 変数には役割が分かる名前をつける(ex. task_without_status)

  • spec/rails_helper.rbに以下を記述すると、FactoryBot.の部分は省略することができるようになる

RSpec.configure do |config|
 #省略
 config.include FactoryBot::Syntax::Methods
end