質問するログイン新規登録

回答編集履歴

13

簡略化

2016/07/26 08:59

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -91,6 +91,6 @@
91
91
 
92
92
  synthesizeImage(/* ...(適宜引数を入れる) */)
93
93
  .then(() => console.log('All Finish!!')) // 最後にここが実行される
94
- .catch(e => console.error((e && e.stack) || e)); // エラー時はここが実行される
94
+ .catch(e => console.error(e.stack || e)); // エラー時はここが実行される
95
95
  ```
96
96
 

12

改善

2016/07/26 08:59

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -24,9 +24,9 @@
24
24
  image.removeEventListener('error', onError);
25
25
  reject(new Error('Failed to load image: ' + source));
26
26
  };
27
- image.src = source;
28
27
  image.addEventListener('load', onLoad);
29
28
  image.addEventListener('error', onError);
29
+ image.src = source;
30
30
  });
31
31
  }
32
32
 
@@ -45,13 +45,12 @@
45
45
  const height = 1620;
46
46
  const context = document.getElementById(canvasId).getContext('2d');
47
47
  context.clearRect(0, 0, width, height);
48
-
48
+
49
49
  // すべてを読み込み終わった後にthenコールバックを実行
50
50
  // そしてこの関数の返り値もPromiseにし,「synthesizeImageが終わった後の処理」を外部からも書けるようにする
51
51
  return Promise
52
52
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
53
53
  .then(images => {
54
-
55
54
  // 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
56
55
  const [shadeImage, ...otherImages] = images;
57
56
 
@@ -66,27 +65,32 @@
66
65
  context.globalCompositeOperation = 'multiply';
67
66
  context.drawImage(shadeImage, 0, 0, width, height);
68
67
 
69
- if (sources !== SRC_ARR.back &&
68
+ if (sources === SRC_ARR.back) return;
70
- sources !== SRC_ARR.right &&
69
+ if (sources === SRC_ARR.right) return;
71
- sources !== SRC_ARR.left) {
70
+ if (sources === SRC_ARR.left) return;
71
+
72
- // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
72
+ // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
73
- // そして,次のthenコールバックをこのPromiseの後に続けるためにreturnする
73
+ // そして,次のthenコールバックをこのPromiseの後に続けるためにreturnする
74
- return loadImageAsync(BTN_FRONT).then(image => {
74
+ return loadImageAsync(BTN_FRONT).then(image => {
75
- context.globalCompositeOperation = 'source-over';
75
+ context.globalCompositeOperation = 'source-over';
76
- context.globalAlpha = 1.0;
76
+ context.globalAlpha = 1.0;
77
- context.drawImage(image, 0, 0, width, height);
77
+ context.drawImage(image, 0, 0, width, height);
78
- console.log('Draw Finish!');
78
+ console.log('Draw Finish!');
79
- });
79
+ });
80
- }
81
- // 条件を満たさないときは何もしない (すぐに次のthenコールバックが実行される)
82
- })
83
- .then(() => console.log('All Finish!!')) // 最後にここが実行される
84
- .catch(e => {
85
- console.error(e.message); // エラー時はここが実行される
86
- throw e; // 更に外部のcatchに繋げさせる
87
80
  });
88
81
  }
89
82
  ```
90
83
 
91
84
  - `btn_front`はグローバル変数のようなので,それと分かるように`SRC_ARR`同様すべて大文字にしました.
92
- - 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.
85
+ - 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.
86
+
87
+ これを呼び出すときは,以下のように必ずエラーに対応する処理も併せて書きます.
88
+
89
+ ```JavaScript
90
+ 'use strict';
91
+
92
+ synthesizeImage(/* ...(適宜引数を入れる) */)
93
+ .then(() => console.log('All Finish!!')) // 最後にここが実行される
94
+ .catch(e => console.error((e && e.stack) || e)); // エラー時はここが実行される
95
+ ```
96
+

11

例外処理修正

2016/07/26 08:06

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -81,7 +81,10 @@
81
81
  // 条件を満たさないときは何もしない (すぐに次のthenコールバックが実行される)
82
82
  })
83
83
  .then(() => console.log('All Finish!!')) // 最後にここが実行される
84
+ .catch(e => {
84
- .catch(() => console.error(e.message)); // エラー時はここが実行される
85
+ console.error(e.message); // エラー時はここが実行される
86
+ throw e; // 更に外部のcatchに繋げさせる
87
+ });
85
88
  }
86
89
  ```
87
90
 

10

comment

2016/07/26 07:45

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -47,7 +47,7 @@
47
47
  context.clearRect(0, 0, width, height);
48
48
 
49
49
  // すべてを読み込み終わった後にthenコールバックを実行
50
- // それにPromiseを返させ,更then繋げ
50
+ // そこの関数の返り値もPromiseし,「synthesizeImageが終わった後処理」を外部からも書けるよう
51
51
  return Promise
52
52
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
53
53
  .then(images => {

9

更に修正

2016/07/26 07:27

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -50,7 +50,7 @@
50
50
  // それにPromiseを返させて,更に次のthenに繋げる
51
51
  return Promise
52
52
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
53
- .then(images => new Promise(resolve => {
53
+ .then(images => {
54
54
 
55
55
  // 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
56
56
  const [shadeImage, ...otherImages] = images;
@@ -70,19 +70,16 @@
70
70
  sources !== SRC_ARR.right &&
71
71
  sources !== SRC_ARR.left) {
72
72
  // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
73
- // そして,次のthenコールバックを発火させるために,resolveを呼び出
73
+ // そして,次のthenコールバックをこのPromiseの後に続けるためにreturn
74
- loadImageAsync(BTN_FRONT).then(image => {
74
+ return loadImageAsync(BTN_FRONT).then(image => {
75
75
  context.globalCompositeOperation = 'source-over';
76
76
  context.globalAlpha = 1.0;
77
77
  context.drawImage(image, 0, 0, width, height);
78
78
  console.log('Draw Finish!');
79
- resolve();
80
79
  });
81
- return;
82
80
  }
83
- // 条件を満たさないときは直ちにresolveを呼び出
81
+ // 条件を満たさないときは何もしない (ぐに次のthenコールバックが実行される)
84
- resolve();
85
- }))
82
+ })
86
83
  .then(() => console.log('All Finish!!')) // 最後にここが実行される
87
84
  .catch(() => console.error(e.message)); // エラー時はここが実行される
88
85
  }

8

return Promise

2016/07/26 07:25

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -36,6 +36,7 @@
36
36
  * @param {string} colorSource - 色付けに用いる画像のURL
37
37
  * @param {string} shadeSource - シェーディングに用いる画像のURL
38
38
  * @param {string} canvasId - canvas要素のid属性値
39
+ * @return {Promise} 次の処理に繋げるためのPromise
39
40
  */
40
41
  function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
41
42
  {
@@ -47,7 +48,7 @@
47
48
 
48
49
  // すべてを読み込み終わった後にthenコールバックを実行
49
50
  // それにPromiseを返させて,更に次のthenに繋げる
50
- Promise
51
+ return Promise
51
52
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
52
53
  .then(images => new Promise(resolve => {
53
54
 
@@ -82,7 +83,7 @@
82
83
  // 条件を満たさないときは直ちにresolveを呼び出す
83
84
  resolve();
84
85
  }))
85
- .then(() => console.log('All Finish!!')); // 最後にここが実行される
86
+ .then(() => console.log('All Finish!!')) // 最後にここが実行される
86
87
  .catch(() => console.error(e.message)); // エラー時はここが実行される
87
88
  }
88
89
  ```

7

例外処理

2016/07/26 07:21

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -12,13 +12,21 @@
12
12
  */
13
13
  function loadImageAsync(source)
14
14
  {
15
- return new Promise(resolve => {
15
+ return new Promise((resolve, reject) => {
16
16
  const image = new Image;
17
+ const onLoad = () => {
18
+ image.removeEventListener('load', onLoad);
19
+ image.removeEventListener('error', onError);
20
+ resolve(image);
21
+ };
22
+ const onError = () => {
23
+ image.removeEventListener('load', onLoad);
24
+ image.removeEventListener('error', onError);
25
+ reject(new Error('Failed to load image: ' + source));
26
+ };
17
27
  image.src = source;
18
- image.addEventListener('load', function self() {
19
- image.removeEventListener('load', self);
28
+ image.addEventListener('load', onLoad);
20
- resolve(image);
29
+ image.addEventListener('error', onError);
21
- });
22
30
  });
23
31
  }
24
32
 
@@ -75,6 +83,7 @@
75
83
  resolve();
76
84
  }))
77
85
  .then(() => console.log('All Finish!!')); // 最後にここが実行される
86
+ .catch(() => console.error(e.message)); // エラー時はここが実行される
78
87
  }
79
88
  ```
80
89
 

6

コメント

2016/07/26 07:18

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -5,6 +5,11 @@
5
5
  ```JavaScript
6
6
  'use strict';
7
7
 
8
+ /**
9
+ * 画像を非同期で読み込む関数
10
+ * @param {string} source - 画像URL
11
+ * @return {Promise} Imageをthenコールバックの第1引数として渡すPromise
12
+ */
8
13
  function loadImageAsync(source)
9
14
  {
10
15
  return new Promise(resolve => {
@@ -17,27 +22,46 @@
17
22
  });
18
23
  }
19
24
 
25
+ /**
26
+ * 画像を合成する関数
27
+ * @param {Array} imageSources - 本体画像のURLの配列
28
+ * @param {string} colorSource - 色付けに用いる画像のURL
29
+ * @param {string} shadeSource - シェーディングに用いる画像のURL
30
+ * @param {string} canvasId - canvas要素のid属性値
31
+ */
20
32
  function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
21
33
  {
34
+ // 幅,高さ,コンテキストを定義
22
35
  const width = 580;
23
36
  const height = 1620;
24
37
  const context = document.getElementById(canvasId).getContext('2d');
25
38
  context.clearRect(0, 0, width, height);
26
39
 
40
+ // すべてを読み込み終わった後にthenコールバックを実行
41
+ // それにPromiseを返させて,更に次のthenに繋げる
27
42
  Promise
28
43
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
29
44
  .then(images => new Promise(resolve => {
45
+
46
+ // 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
30
47
  const [shadeImage, ...otherImages] = images;
48
+
49
+ // otherImagesの全要素についてsource-overで描画を実行
31
50
  for (const image of otherImages) {
32
51
  context.globalCompositeOperation = 'source-over';
33
52
  context.globalAlpha = 1.0;
34
53
  context.drawImage(image, 0, 0, width, height);
35
54
  }
55
+
56
+ // shadeImageについてmultiplyで描画を実行
36
57
  context.globalCompositeOperation = 'multiply';
37
58
  context.drawImage(shadeImage, 0, 0, width, height);
59
+
38
60
  if (sources !== SRC_ARR.back &&
39
61
  sources !== SRC_ARR.right &&
40
62
  sources !== SRC_ARR.left) {
63
+ // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
64
+ // そして,次のthenコールバックを発火させるために,resolveを呼び出す
41
65
  loadImageAsync(BTN_FRONT).then(image => {
42
66
  context.globalCompositeOperation = 'source-over';
43
67
  context.globalAlpha = 1.0;
@@ -47,9 +71,10 @@
47
71
  });
48
72
  return;
49
73
  }
74
+ // 条件を満たさないときは直ちにresolveを呼び出す
50
75
  resolve();
51
76
  }))
52
- .then(() => console.log('All Finish!!'));
77
+ .then(() => console.log('All Finish!!')); // 最後にここが実行される
53
78
  }
54
79
  ```
55
80
 

5

Finish修正

2016/07/26 07:07

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -26,7 +26,7 @@
26
26
 
27
27
  Promise
28
28
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
29
- .then(images => {
29
+ .then(images => new Promise(resolve => {
30
30
  const [shadeImage, ...otherImages] = images;
31
31
  for (const image of otherImages) {
32
32
  context.globalCompositeOperation = 'source-over';
@@ -43,10 +43,13 @@
43
43
  context.globalAlpha = 1.0;
44
44
  context.drawImage(image, 0, 0, width, height);
45
45
  console.log('Draw Finish!');
46
+ resolve();
46
47
  });
48
+ return;
47
49
  }
48
- console.log('All Finish!');
50
+ resolve();
49
- });
51
+ }))
52
+ .then(() => console.log('All Finish!!'));
50
53
  }
51
54
  ```
52
55
 

4

constつけ忘れた

2016/07/26 06:55

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -27,7 +27,7 @@
27
27
  Promise
28
28
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
29
29
  .then(images => {
30
- [shadeImage, ...otherImages] = images;
30
+ const [shadeImage, ...otherImages] = images;
31
31
  for (const image of otherImages) {
32
32
  context.globalCompositeOperation = 'source-over';
33
33
  context.globalAlpha = 1.0;

3

case統一

2016/07/26 06:52

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -17,11 +17,11 @@
17
17
  });
18
18
  }
19
19
 
20
- function synthesizeImage(imageSources, colorSource, shadeSource, canvas_id)
20
+ function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
21
21
  {
22
22
  const width = 580;
23
23
  const height = 1620;
24
- const context = document.getElementById(canvas_id).getContext('2d');
24
+ const context = document.getElementById(canvasId).getContext('2d');
25
25
  context.clearRect(0, 0, width, height);
26
26
 
27
27
  Promise
@@ -38,7 +38,7 @@
38
38
  if (sources !== SRC_ARR.back &&
39
39
  sources !== SRC_ARR.right &&
40
40
  sources !== SRC_ARR.left) {
41
- loadImageAsync(btn_front).then(image => {
41
+ loadImageAsync(BTN_FRONT).then(image => {
42
42
  context.globalCompositeOperation = 'source-over';
43
43
  context.globalAlpha = 1.0;
44
44
  context.drawImage(image, 0, 0, width, height);
@@ -48,4 +48,7 @@
48
48
  console.log('All Finish!');
49
49
  });
50
50
  }
51
- ```
51
+ ```
52
+
53
+ - `btn_front`はグローバル変数のようなので,それと分かるように`SRC_ARR`同様すべて大文字にしました.
54
+ - 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.

2

ミス

2016/07/26 06:51

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -26,7 +26,8 @@
26
26
 
27
27
  Promise
28
28
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
29
+ .then(images => {
29
- .then((shadeImage, ...otherImages) => {
30
+ [shadeImage, ...otherImages] = images;
30
31
  for (const image of otherImages) {
31
32
  context.globalCompositeOperation = 'source-over';
32
33
  context.globalAlpha = 1.0;

1

変数名

2016/07/26 06:48

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -8,16 +8,16 @@
8
8
  function loadImageAsync(source)
9
9
  {
10
10
  return new Promise(resolve => {
11
- const img = new Image;
11
+ const image = new Image;
12
- img.src = source;
12
+ image.src = source;
13
- img.addEventListener('load', function self() {
13
+ image.addEventListener('load', function self() {
14
- img.removeEventListener('load', self);
14
+ image.removeEventListener('load', self);
15
- resolve(img);
15
+ resolve(image);
16
16
  });
17
17
  });
18
18
  }
19
19
 
20
- function synthesizeImage(sources, color, shade, canvas_id)
20
+ function synthesizeImage(imageSources, colorSource, shadeSource, canvas_id)
21
21
  {
22
22
  const width = 580;
23
23
  const height = 1620;
@@ -25,22 +25,22 @@
25
25
  context.clearRect(0, 0, width, height);
26
26
 
27
27
  Promise
28
- .all([shade, color, ...sources].map(loadImageAsync))
28
+ .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
29
- .then((shade, ...images) => {
29
+ .then((shadeImage, ...otherImages) => {
30
- for (const img of images) {
30
+ for (const image of otherImages) {
31
31
  context.globalCompositeOperation = 'source-over';
32
32
  context.globalAlpha = 1.0;
33
- context.drawImage(img, 0, 0, width, height);
33
+ context.drawImage(image, 0, 0, width, height);
34
34
  }
35
35
  context.globalCompositeOperation = 'multiply';
36
- context.drawImage(shade, 0, 0, width, height);
36
+ context.drawImage(shadeImage, 0, 0, width, height);
37
37
  if (sources !== SRC_ARR.back &&
38
38
  sources !== SRC_ARR.right &&
39
39
  sources !== SRC_ARR.left) {
40
- loadImageAsync(btn_front).then(img => {
40
+ loadImageAsync(btn_front).then(image => {
41
41
  context.globalCompositeOperation = 'source-over';
42
42
  context.globalAlpha = 1.0;
43
- context.drawImage(img, 0, 0, width, height);
43
+ context.drawImage(image, 0, 0, width, height);
44
44
  console.log('Draw Finish!');
45
45
  });
46
46
  }