JavaScriptの非同期処理

setTimeoutを用いた非同期処理

		console.log(1);
		setTimeout(()=> console.log(2), 5000);
		console.log(3);

1->3->2の順番で処理される

		const sleep = (second) => {
			const startTime = new Date();
			while (new Date() - startTime < second);
			console.log("done sleep");
		}

		const button = document.querySelector("button");

		button.addEventListener("click", () => console.log("clicked"));

		sleep(5000)

処理される順番 : setTimeout実行中に次のタスクが実行される

		const first = () => {
			setTimeout(() => console.log("task1 done"), 2000);
			console.log("function frist done");
		}

		const second = () => console.log("function second done");

		first();
		second();

### Promiseとは?
Promiseとは非同期処理をより簡単かつ可動性が上がるように書けるようにしたJavaScriptのオブジェクト
Promiseは3つの状態がある
– pending: 非同期処理の実行中の状態を表す
– fulfilled: 非同期処理が正常終了した状態を表す
– rejected: 非同期処理が異常終了した状態を表す

new Promise(

).then(

).catch(

).finally(
);

引数としてコールバック関数をとる

new Promise((resolve, reject) => {

}).then(

).catch(

).finally(

);

### resolve
Promiseの状態がfulfilled(正常終了)になったらresolveが実行される
resolveが実行された場合は、thenメソッドが実行される
thenメソッドが実行された場合catchメソッドはm無視され、最後にfinallyメソッドが実行される

new Promise((resolve, reject) => {
	resolve("hoge");
}).then((data)=>console.log(data)

).catch(

).finally(()=>console.log("finally")

);

### reject
Promiseの状態がrejectedになったらrejectが実行される
rejectはPromise内のコールバック実行中に何らかのエラーが発生しそれをPromiseに通知するために使用する関数
rejectが実行される場合はcatchメソッドのコールバック関数が実行される

new Promise((resolve, reject) => reject("fuga")
.then(
).catch((data)=> console.log(data))
.finally(()=>console.log("finally")
);

Promiseオブジェクト内の同期・非同期処理の関係

new Promise((resolve, reject) => {
 // 同期処理
}).then(
 // resolveの実行を待って非同期処理
).catch(
 // rejectの実行を待って非同期処理
).finally(
 // resolveかrejectの実行を待って非同期処理
);
	new Promise((resolve, reject) => {
	 console.log("Promise");
	  resolve();
	}).then(() => console.log("then"));

	console.log("global end");

Promiseオブジェクトを使った並列処理
– Promise.all => 並列処理している全てが完了したら後続処理に続く

	const sleep = (val) => {
		return new Promise((resolve) => {
			setTimeout(() => {
				console.log(val++);
				resolve(val);
			}, 1000);
		});
	};

	Promise.all([sleep(0), sleep(1), sleep(2)]).then(() => console.log("end"));

AsyncとAwait
AsyncとAwaitはPromiseを更に直感的に書けるようにしたもの

– Async
Asyncを使って宣言された関数はPromiseオブジェクトを返却する
関数宣言の先頭にAsyncがついていたらPromiseオブジェクトがreturnされる。thenメソッドにつなげられる。

– Await
AwaitはPromiseを返却する関数の非同期処理が終わるのを待つ記述
Awaitで受けられるものはPromiseのインスタンス

	const sleep = (val) => {
		return new Promise((resolve) => {
			setTimeout(() => {
				resolve(val);
			}, 1000);
		});
	};

	async function init() {
		console.log(await sleep(0));
	}

	init();

fetchという関数
fetchを使うことでサーバからデータを取得できる

	fetch("")
		.then((response) => {
			return response.json();
		})
		.then((json) => {
			console.log(json);
		});

JSの半角→全角変換

<script>
	function zenkaku2Hankaku(str){
		return str.replace(/[A-Za-z0-9]/g, function(s){
			return String.fromCharCode(s.charCodeAt(0) + 0xFEE0);
		});
	}

	console.log(zenkaku2Hankaku("123abC"));
</script>

JSで書く場合も基本はスクリプトの中に辞書を持って変換しているのね。
仕組みを理解した。

[JavaScript] ファイル名とファイルの中身を取得する

ブロックチェーン上に上げるために、ファイル名とファイルの中身を取得したい。

html

				<div class="control">
					<input id="file" name="file" type="file" />
				</div>
				// 省略
		<p>Please press the button.</p>
		<input type="submit" class="button is-link" id="btn" value="authorize" onclick="OnButtonClick();">

view: buttonを押すと処理を実行するように書いている(onChangeではない)

reader.readAsTextとした後に、reader.onload(ファイルの読み込み完了) 後に処理をする。

		let reader = new FileReader();
		let input = ""

		function OnButtonClick() {
			input = document.getElementById("file").files[0]
			reader.readAsText(input, 'UTF-8')
			reader.onload = ()=> {
	            main();	
	        };
						
		}
		async function main() {
			console.log(input.name)
			console.log(reader.result);
		}

なるほどー、割と簡単にできたなー

[JavaScript] inputに入力があれbuttonを押せるようにする

btn.disabled = true; でbuttonを制御します。
input.addEventListener(“change”, func); で btn.disabledの状態を変更する

let btn = document.getElementById('btn');
		let wallet = document.getElementById('wallet');
		let message = document.getElementById('message');
		let amount = document.getElementById('amount');
		let resArea = document.getElementById("resArea");
		btn.disabled = true; 
		wallet.addEventListener("change", stateHandle);
		amount.addEventListener("change", stateHandle);
		message.addEventListener("change", stateHandle);
		function stateHandle() {
		  if (wallet.value == "" || amount.value == "") {
		    btn.disabled = true; 
		  } else {
		    btn.disabled = false;
		  }
		}

		function OnButtonClick() {
			if (!wallet.value || !message.value || !amount.value) {
			    resArea.innerHTML = "Wallet Address、amount、messageを入力してください";
			} else {
			    main();
			}		
			
		}
		async function main() {
			console.log("送金完了しました")
			console.log(wallet.value)
			console.log(message.value)
			console.log(amount.value)
			resArea.innerHTML = "送金完了しました";
		}

最初

入力後

OK
これで実際に送金できるかテストする

しゃあああああああああああああああああああ
次はxem amountの取得かな

[javascript] ページ離脱時にポップアップ表示

ページ離脱時にポップアップ表示
formのsubmitの際はポップアップ非表示

<h1>商品ページ</h1>
	<form action="/" method="get" id="form" class="form-example">
	  <div class="form-example">
	    <label for="name">商品名: </label>
	    <input type="text" name="name" id="name" value="チョコレート">
	  </div>
	  <div class="form-example">
	    <label for="name">購入者名: </label>
	    <input type="text" name="name" id="name">
	  </div>
	  <div class="form-example">
	    <label for="email">個数: </label>
	    <input type="number" name="number" value="1">
	  </div>
	  <div class="form-example">
	    <input type="submit" value="今すぐ購入">
	  </div>
	</form>
	<br><br>
	<a href="/">リンク</a>
	<script>

		var onBeforeunloadHandler = function(e) {
    		e.returnValue = 'ページから離れます。よろしいでしょうか?';
		};
		window.addEventListener('beforeunload', onBeforeunloadHandler, false);

		const path = location.pathname;

		var cookies = document.cookie; 
		var cookiesArray = cookies.split(';'); 

		for(var c of cookiesArray){ 
		    var cArray = c.split('='); 
		    if( cArray[0] == 'page' && cArray[1] == path){ 
		        window.removeEventListener('beforeunload', onBeforeunloadHandler, false);
		    }
		}		

		const form = document.getElementById('form');
		form.addEventListener('submit', function(e) {
		    window.removeEventListener('beforeunload', onBeforeunloadHandler, false);
		}, false);

		var date1,date2;
		var kigen = 1;
		date1 = new Date();
		date1.setTime(date1.getTime() + kigen*24*60*60*1000);
		date2 = date1.toGMTString();

		document.cookie = "page=" + path+";expires=" + date2;
	</script>

html・Javascriptでwebカメラを使用する方法

<h1>Webカメラの映像表示</h1>
	<div>
		<video id="video" width="600px" height="400px"></video>
	</div>
	<script>
		const video = document.getElementById("video")
		navigator.mediaDevices.getUserMedia({
			video: true,
			audio: false,
		}).then(stream => {
			video.srcObject = stream;
			video.play()
		}).catch(e => {
			console.log(e)
		})
	</script>

このファイルが次の許可を求めていますと表示される。

OK これでjsのopenCVを使いたい

[Amazon Kinesis Video Stream] VideoJSでHTML側で取得して表示

KVSのHLSStreamingSessionURLを取得してvideojsでストリーミング表示する

credentials.js

const AWS_ACCESS_KEY_ID = '';
const AWS_SECRET_ACCESS_KEY = '';
const AWS_REGION = 'ap-northeast-1';
const AWS_STREAM_NAME = 'MyKinesisVideoStream';

html

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet" />
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.642.0.min.js"></script>
    <script src="credentials.js"></script>
</head>
<body>
    <video id="videojs" class="player video-js vjs-default-skin" data-setup='{"fluid":true}' controls autoplay muted></video>

    <script src="https://vjs.zencdn.net/7.15.4/video.min.js"></script>
    <script>
        window.addEventListener("unhandledrejection", function(event){
            console.warn("WARNING: Unhandled promise rejection." + event.reason);
            location.reload()
        });
        window.onerror = (message, file, lineNo, colNo, error) => {
            console.error('window.onerror', message, file, lineNo, colNo, error);
            location.reload()
        }

        async function getURL(){
            const accessKeyId = AWS_ACCESS_KEY_ID;
            const secretAccessKey = AWS_SECRET_ACCESS_KEY;
            const region = AWS_REGION;
            const streamName = AWS_STREAM_NAME;

            const options = {
                accessKeyId: accessKeyId,
                secretAccessKey: secretAccessKey,
                region: region,
            }
            const kinesisVideoClient = new AWS.KinesisVideo(options);
            const kinesisVideoArchivedMediaClient = new AWS.KinesisVideoArchivedMedia(options);

            const e = await kinesisVideoClient.getDataEndpoint({
                APIName: 'GET_HLS_STREAMING_SESSION_URL',
                StreamName: streamName
            }).promise();
            kinesisVideoArchivedMediaClient.endpoint = new AWS.Endpoint(e.DataEndpoint);

            const d = await kinesisVideoArchivedMediaClient.getHLSStreamingSessionURL({
                DisplayFragmentTimestamp: 'ALWAYS',
                StreamName: streamName
            }).promise();
            return d.HLSStreamingSessionURL;
        }

        document.addEventListener('DOMContentLoaded', async() => {
            const url = await getURL();
            const player = videojs('videojs');
            player.src({
                src: url,
                type: 'application/x-mpegURL'
            });
            player.on('error', function(){
                console.log(player.error());
                location.reload();
            });
            setInterval(() => {
                const t = player.currentTime();
                console.log("current Time is "+ t +" seconds");
            }, 5000)
        });
    </script>
</body>
</html>

### mac
kvsのsdkをdownloadした状態とする
https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git

macのカメラからKVSに映像を送る
$ gst-launch-1.0 avfvideosrc device-index=0 ! videoconvert ! video/x-raw,format=I420,width=1280,height=720 ! vtenc_h264_hw allow-frame-reordering=FALSE realtime=TRUE max-keyframe-interval=45 bitrate=512 ! h264parse ! video/x-h264,stream-format=avc,alignment=au,profile=baseline ! kvssink stream-name=MyKinesisVideoStream storage-size=512 access-key=”${access-key}” secret-key=”${secret-key}” aws-region=”ap-northeast-1″

$ php -S 192.168.34.10:8000
http://192.168.34.10:8000/

ちょっと待ってくれ
なんか凄い事やってる様な気がする…🥺

[Lazy Load] 画像の遅延ロードの書き方

class=”lazyload”とし、画像はdata-srcで読み込む。
lazyloadはcdnで読み込み、scriptでlazyload();とする。

	<img class="lazyload" data-src="img/1.jpg" width="300" height="200"><br><br><br><br>
	<img class="lazyload" data-src="img/2.jpg" width="300" height="200"><br><br><br><br>
	<img class="lazyload" data-src="img/3.jpg" width="300" height="200">
	<script src="https://cdn.jsdelivr.net/npm/lazyload@2.0.0-rc.2/lazyload.min.js"></script>
	<script>
    lazyload();
	</script>

Googleのdevtoolで確認すると、3枚あるのが2枚しか読み込まれていないことがわかる。

なかなかやりおる

[JavaScript] Classの追加(add)を操作する

タブメニューで、URLのパスに応じてメニューのis-activeをつけたい時
L ulのli要素にclassで”is-active”をつけたい
html

<div class="tabs">
      	<ul id="mylist">
      		<li><a href="/btc">BTC</a></li>
      		<li><a href="/eth">ETH</a></li>
      		<li><a href="/xrp">EXP</a></li>
      		<li><a href="/xlm">XLM</a></li>
      		<li><a href="/mona">MONA</a></li>
      	</ul>
      </div>

javascript側
L location.pathnameでURLを取得する
  L querySelectorAllでli要素を全て取得する
  L classList.addでclassを付与する

const pathname = location.pathname;
  	var i;
  	switch(pathname){
  		case '/btc':
  			i = 0;break;
  		case '/eth':
  			i = 1;break;
  		case '/xrp':
  			i = 2;break;
  		case '/xlm':
  			i = 3;break;
  		case '/mona':
  			i = 4;break;
  	}
  	var cols = document.querySelectorAll('#mylist li');
  	cols[i].classList.add('is-active');

OK
やりたいことの7割くらいまでは出来た

fetchAPI

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- <link rel="stylesheet" type="text/css" href="styles.css"> -->
</head>
<body>
  <select id="sel">
      <option> --場所を選ぶ-- </option>
      <option value="kyoto">京都</option>
      <option value="osaka">大阪</option>
      <option value="kobe">神戸</option>
  </select>

  <div id="mes">
    集合場所は<span id="pos"></span>
    集合時刻は<span id="time"></span>
  </div>
    <script>
      const url = "ajax_getData.php";
      let selid = document.getElementById('sel');

      selid.addEventListener('change', function(){
        let optval = selid.options[selid.selectedIndex].value;
        let param = new URLSearchParams();
        param.append("opt",optval);

        fetch(url, {
          method: "post",
          body: param,
        }).then(response => {
            if(response.ok){
              let promise = response.json();
              promise.then(data =>{
                document.getElementById('pos').innerHTML = data.position;
                document.getElementById('time').innerHTML = data.ap_time;
              })
            } else {
              alert("request failed");
            }
        })
      })
    </script>
</body>
</html>

なるほど。。。
ajaxの取得をtime intervalで数秒ごとに取るようにして表示すれば良いのか。
ほぼほぼロジックも出来たので背景処理のところだな