質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

894閲覧

JavaScript Array.fromを使う事を条件でsleepを実現したい

vcxr

総合スコア17

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/09/11 00:22

編集2021/09/11 00:47

Array.fromを使う事を条件としたsleepを実現したいです
下記コードだと一瞬で全て赤に変わりますが
1個変わったら0.5秒あけて1個変えて0.5秒あけてを繰り返したいです
どういうコードで実現できるでしょうか

<script> window.onload=function(){ Array.from(document.querySelectorAll('div'), item => { item.style.background="red"; }); } </script> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> <div>10</div>
リアルタイムに1個づつ色が変わる、という動きにならない・・・ <script> window.onload=function(){ Array.from(document.querySelectorAll('div'), item => { item.style.background="red"; const d1 = new Date(); while (true) { const d2 = new Date(); if (d2 - d1 > 1000) { break; } } }); } </script> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> <div>10</div>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

手段が目的化

Array.fromを使う事を条件としたsleepを実現したいです

手段が目的化しています。
目的を見据えて、手段を選択するのがスマートなコードを書くコツだと思います。

window.setTimeout()

setTimeout() は「非同期処理」の「コールバック処理」であり、配列化による恩恵はあまりありません。

HTML

1<div>1</div> 2<div>2</div> 3<div>3</div> 4<div>4</div> 5<div>5</div> 6<div>6</div> 7<div>7</div> 8<div>8</div> 9<div>9</div> 10<div>10</div> 11 12<script> 13'use strict'; 14setTimeout(function handleTimeout (div, config) { 15 div[config.i++].style.backgroundColor = 'red'; 16 setTimeout(handleTimeout, 500, ...arguments); 17}, 500, document.querySelectorAll('div'), {i: 0}); 18</script>

Promise

Promise の逐次処理」と相性の良い Array.prototype.reduce() を使う為に Array.from() を活用するケースは考えられます。

HTML

1<div>1</div> 2<div>2</div> 3<div>3</div> 4<div>4</div> 5<div>5</div> 6<div>6</div> 7<div>7</div> 8<div>8</div> 9<div>9</div> 10<div>10</div> 11 12<script> 13'use strict'; 14function createTimeoutCallFn (div) { 15 return () => new Promise((resolve, reject) => { 16 setTimeout(div => { 17 div.style.backgroundColor = 'red'; 18 resolve(); 19 }, 500, div); 20 }); 21} 22 23Array.from(document.querySelectorAll('div')).reduce((promise, div) => promise.then(createTimeoutCallFn(div)), Promise.resolve()); 24</script>

ただし、Array.prototype.reduce() を使用しなくても実装可能です。

HTML

1<div>1</div> 2<div>2</div> 3<div>3</div> 4<div>4</div> 5<div>5</div> 6<div>6</div> 7<div>7</div> 8<div>8</div> 9<div>9</div> 10<div>10</div> 11 12<script> 13'use strict'; 14function createTimeoutCallFn (div) { 15 return () => new Promise((resolve, reject) => { 16 setTimeout(div => { 17 div.style.backgroundColor = 'red'; 18 resolve(); 19 }, 500, div); 20 }); 21} 22 23let promise = Promise.resolve(); 24 25for (let div of document.querySelectorAll('div')) { 26 promise = promise.then(createTimeoutCallFn(div)); 27} 28</script>

Re: vcxr さん

投稿2021/09/11 12:30

think49

総合スコア18189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2021/09/11 12:39 編集

「Array.fromを使う」という「手段」を元に「配列を使うべき目的」を逆算しましたが、やはり、順序が逆だと思います。
guest

0

ベストアンサー

javascript

1window.onload = function() { 2 3 const fncs = Array.from(document.querySelectorAll('div'), item => () => 4 new Promise(resolve => { 5 setTimeout(() => { 6 item.style.background = "red"; 7 resolve(); 8 }, 500); 9 }) 10 ); 11 12 (async () => { 13 for (const f of fncs) { 14 await f(); 15 } 16 })(); 17 18}

サンプル

上のやつあかんわ。なんや難しく考えすぎとった。

上のやつ、一応ソレっぽく動くけど、なんや難しく考えすぎとったわ。

これでええやん:

javascript

1const sleep = (millisec) => new Promise(resolve => { 2 setTimeout(resolve, millisec); 3});

ゆうsleep作っておいてからの

javascript

1window.onload = async function() { 2 3 const items = Array.from(document.querySelectorAll('div')); 4 5 for (const item of items) { 6 await sleep(500); 7 item.style.background = "red"; 8 } 9 10} 11

でええわいね ➡ サンプル

さらに上のコード詰めるとすると、 質問の前提としてはArray.from 使うんがお題ゆうことやけど、for ... of でループさせるもんを配列にしとかなあかんわけではないねんから、コレでええやろ思いますー

補足

質問者さんが知りたいのは、「(for (...of ... )使えばできるのは分かった。そやけど) Array.from の第二引数として渡す関数、item => { ・・・・ } の中で、divの背景を赤にする

javascript

1item.style.background = "red";

の直前で0.5秒待つゆう処理を入れてできへんの? 」ゆうことかもしれへんね。
それだとすると、一応、こないにすればできる。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <script> 7 8 const sleepersGenerator = async function* (milliseconds) { 9 while (true) { 10 yield new Promise(resolve => { setTimeout(resolve, milliseconds); }); 11 } 12 } 13 14 window.onload = function() { 15 const sleepers = sleepersGenerator(500); 16 Array.from(document.querySelectorAll('div'), async item => { 17 await sleepers.next(); 18 item.style.background = "red"; 19 }) 20 } 21 22 </script> 23</head> 24<body> 25<div>1</div> 26<div>2</div> 27<div>3</div> 28<div>4</div> 29<div>5</div> 30<div>6</div> 31<div>7</div> 32<div>8</div> 33<div>9</div> 34<div>10</div> 35</body> 36</html>

上のコード、コピペしたHTMLファイル作ってブラウザに表示すれば期待されてる動きになっとる思いますう。(さきほど、一応ゆうたのは、sleepersGeneratorん中が、while(true) になとって、sleepersが終わらないイテレータになってしまうところが、ちょっとキモチワルイという点ですねん。)

そやけど、上のコードでも Array.from 使うんは「何か変」て感じや。なんでゆうたらArray.fromが返す配列を使ってないからのう。こういうときは、document.querySelectorAll('div') の返した要素のリストに対して、forEach使えばええ。

diff

1- Array.from(document.querySelectorAll('div'), async item => { 2+ document.querySelectorAll('div').forEach(async item => {

投稿2021/09/11 02:34

編集2021/09/11 19:04
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

while()で回っている間、リペイントが起こらないので、赤くしても最後まで再描画されません。

<div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> <div>10</div> <script> const _sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const toRed = async (elem,ms) => { await _sleep(ms); elem.style.background="red"; } window.onload=function(){ const a = Array.from(document.querySelectorAll('div')); for (let i = 0; i < a.length; i++) { toRed(a[i], i*500); } } </script>

投稿2021/09/11 01:48

itagagaki

総合スコア8402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問