回答編集履歴

13

簡略化

2016/07/26 08:59

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -184,7 +184,7 @@
184
184
 
185
185
  .then(() => console.log('All Finish!!')) // 最後にここが実行される
186
186
 
187
- .catch(e => console.error((e && e.stack) || e)); // エラー時はここが実行される
187
+ .catch(e => console.error(e.stack || e)); // エラー時はここが実行される
188
188
 
189
189
  ```
190
190
 

12

改善

2016/07/26 08:59

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -50,11 +50,11 @@
50
50
 
51
51
  };
52
52
 
53
- image.src = source;
54
-
55
53
  image.addEventListener('load', onLoad);
56
54
 
57
55
  image.addEventListener('error', onError);
56
+
57
+ image.src = source;
58
58
 
59
59
  });
60
60
 
@@ -92,7 +92,7 @@
92
92
 
93
93
  context.clearRect(0, 0, width, height);
94
94
 
95
-
95
+
96
96
 
97
97
  // すべてを読み込み終わった後にthenコールバックを実行
98
98
 
@@ -103,8 +103,6 @@
103
103
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
104
104
 
105
105
  .then(images => {
106
-
107
-
108
106
 
109
107
  // 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
110
108
 
@@ -134,41 +132,29 @@
134
132
 
135
133
 
136
134
 
137
- if (sources !== SRC_ARR.back &&
135
+ if (sources === SRC_ARR.back) return;
138
136
 
139
- sources !== SRC_ARR.right &&
137
+ if (sources === SRC_ARR.right) return;
140
138
 
141
- sources !== SRC_ARR.left) {
139
+ if (sources === SRC_ARR.left) return;
142
140
 
143
- // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
144
141
 
145
- // そして,次のthenコールバックをこのPromiseの後に続けるためにreturnする
146
142
 
147
- return loadImageAsync(BTN_FRONT).then(image => {
143
+ // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
148
144
 
149
- context.globalCompositeOperation = 'source-over';
145
+ // そして,次のthenコールバックをこのPromiseの後に続けるためにreturnする
150
146
 
151
- context.globalAlpha = 1.0;
147
+ return loadImageAsync(BTN_FRONT).then(image => {
152
148
 
153
- context.drawImage(image, 0, 0, width, height);
149
+ context.globalCompositeOperation = 'source-over';
154
150
 
155
- console.log('Draw Finish!');
151
+ context.globalAlpha = 1.0;
156
152
 
157
- });
153
+ context.drawImage(image, 0, 0, width, height);
158
154
 
159
- }
155
+ console.log('Draw Finish!');
160
156
 
161
- // 条件を満たさないときは何もしない (すぐに次のthenコールバックが実行される)
162
-
163
- })
157
+ });
164
-
165
- .then(() => console.log('All Finish!!')) // 最後にここが実行される
166
-
167
- .catch(e => {
168
-
169
- console.error(e.message); // エラー時はここが実行される
170
-
171
- throw e; // 更に外部のcatchに繋げさせる
172
158
 
173
159
  });
174
160
 
@@ -181,3 +167,27 @@
181
167
  - `btn_front`はグローバル変数のようなので,それと分かるように`SRC_ARR`同様すべて大文字にしました.
182
168
 
183
169
  - 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.
170
+
171
+
172
+
173
+ これを呼び出すときは,以下のように必ずエラーに対応する処理も併せて書きます.
174
+
175
+
176
+
177
+ ```JavaScript
178
+
179
+ 'use strict';
180
+
181
+
182
+
183
+ synthesizeImage(/* ...(適宜引数を入れる) */)
184
+
185
+ .then(() => console.log('All Finish!!')) // 最後にここが実行される
186
+
187
+ .catch(e => console.error((e && e.stack) || e)); // エラー時はここが実行される
188
+
189
+ ```
190
+
191
+
192
+
193
+

11

例外処理修正

2016/07/26 08:06

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -164,7 +164,13 @@
164
164
 
165
165
  .then(() => console.log('All Finish!!')) // 最後にここが実行される
166
166
 
167
+ .catch(e => {
168
+
167
- .catch(() => console.error(e.message)); // エラー時はここが実行される
169
+ console.error(e.message); // エラー時はここが実行される
170
+
171
+ throw e; // 更に外部のcatchに繋げさせる
172
+
173
+ });
168
174
 
169
175
  }
170
176
 

10

comment

2016/07/26 07:45

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -96,7 +96,7 @@
96
96
 
97
97
  // すべてを読み込み終わった後にthenコールバックを実行
98
98
 
99
- // それにPromiseを返させて更に次のthen繋げ
99
+ // そしてこの関数の返り値もPromiseにし「synthesizeImageが終わった後の処理」を外部からも書けるよう
100
100
 
101
101
  return Promise
102
102
 

9

更に修正

2016/07/26 07:27

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -102,7 +102,7 @@
102
102
 
103
103
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
104
104
 
105
- .then(images => new Promise(resolve => {
105
+ .then(images => {
106
106
 
107
107
 
108
108
 
@@ -142,9 +142,9 @@
142
142
 
143
143
  // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
144
144
 
145
- // そして,次のthenコールバックを発火させるためにresolveを呼び出
145
+ // そして,次のthenコールバックをこのPromiseの後に続けるためにreturn
146
146
 
147
- loadImageAsync(BTN_FRONT).then(image => {
147
+ return loadImageAsync(BTN_FRONT).then(image => {
148
148
 
149
149
  context.globalCompositeOperation = 'source-over';
150
150
 
@@ -154,19 +154,13 @@
154
154
 
155
155
  console.log('Draw Finish!');
156
156
 
157
- resolve();
158
-
159
157
  });
160
-
161
- return;
162
158
 
163
159
  }
164
160
 
165
- // 条件を満たさないときは直ちresolveを呼び出す
161
+ // 条件を満たさないときは何もしない (すぐ次のthenコールバックが実行される)
166
162
 
167
- resolve();
168
-
169
- }))
163
+ })
170
164
 
171
165
  .then(() => console.log('All Finish!!')) // 最後にここが実行される
172
166
 

8

return Promise

2016/07/26 07:25

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -74,6 +74,8 @@
74
74
 
75
75
  * @param {string} canvasId - canvas要素のid属性値
76
76
 
77
+ * @return {Promise} 次の処理に繋げるためのPromise
78
+
77
79
  */
78
80
 
79
81
  function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
@@ -96,7 +98,7 @@
96
98
 
97
99
  // それにPromiseを返させて,更に次のthenに繋げる
98
100
 
99
- Promise
101
+ return Promise
100
102
 
101
103
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
102
104
 
@@ -166,7 +168,7 @@
166
168
 
167
169
  }))
168
170
 
169
- .then(() => console.log('All Finish!!')); // 最後にここが実行される
171
+ .then(() => console.log('All Finish!!')) // 最後にここが実行される
170
172
 
171
173
  .catch(() => console.error(e.message)); // エラー時はここが実行される
172
174
 

7

例外処理

2016/07/26 07:21

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -26,19 +26,35 @@
26
26
 
27
27
  {
28
28
 
29
- return new Promise(resolve => {
29
+ return new Promise((resolve, reject) => {
30
30
 
31
31
  const image = new Image;
32
32
 
33
- image.src = source;
33
+ const onLoad = () => {
34
34
 
35
- image.addEventListener('load', function self() {
35
+ image.removeEventListener('load', onLoad);
36
36
 
37
- image.removeEventListener('load', self);
37
+ image.removeEventListener('error', onError);
38
38
 
39
39
  resolve(image);
40
40
 
41
- });
41
+ };
42
+
43
+ const onError = () => {
44
+
45
+ image.removeEventListener('load', onLoad);
46
+
47
+ image.removeEventListener('error', onError);
48
+
49
+ reject(new Error('Failed to load image: ' + source));
50
+
51
+ };
52
+
53
+ image.src = source;
54
+
55
+ image.addEventListener('load', onLoad);
56
+
57
+ image.addEventListener('error', onError);
42
58
 
43
59
  });
44
60
 
@@ -152,6 +168,8 @@
152
168
 
153
169
  .then(() => console.log('All Finish!!')); // 最後にここが実行される
154
170
 
171
+ .catch(() => console.error(e.message)); // エラー時はここが実行される
172
+
155
173
  }
156
174
 
157
175
  ```

6

コメント

2016/07/26 07:18

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -11,6 +11,16 @@
11
11
  'use strict';
12
12
 
13
13
 
14
+
15
+ /**
16
+
17
+ * 画像を非同期で読み込む関数
18
+
19
+ * @param {string} source - 画像URL
20
+
21
+ * @return {Promise} Imageをthenコールバックの第1引数として渡すPromise
22
+
23
+ */
14
24
 
15
25
  function loadImageAsync(source)
16
26
 
@@ -36,9 +46,25 @@
36
46
 
37
47
 
38
48
 
49
+ /**
50
+
51
+ * 画像を合成する関数
52
+
53
+ * @param {Array} imageSources - 本体画像のURLの配列
54
+
55
+ * @param {string} colorSource - 色付けに用いる画像のURL
56
+
57
+ * @param {string} shadeSource - シェーディングに用いる画像のURL
58
+
59
+ * @param {string} canvasId - canvas要素のid属性値
60
+
61
+ */
62
+
39
63
  function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
40
64
 
41
65
  {
66
+
67
+ // 幅,高さ,コンテキストを定義
42
68
 
43
69
  const width = 580;
44
70
 
@@ -50,13 +76,25 @@
50
76
 
51
77
 
52
78
 
79
+ // すべてを読み込み終わった後にthenコールバックを実行
80
+
81
+ // それにPromiseを返させて,更に次のthenに繋げる
82
+
53
83
  Promise
54
84
 
55
85
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
56
86
 
57
87
  .then(images => new Promise(resolve => {
58
88
 
89
+
90
+
91
+ // 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
92
+
59
93
  const [shadeImage, ...otherImages] = images;
94
+
95
+
96
+
97
+ // otherImagesの全要素についてsource-overで描画を実行
60
98
 
61
99
  for (const image of otherImages) {
62
100
 
@@ -68,15 +106,25 @@
68
106
 
69
107
  }
70
108
 
109
+
110
+
111
+ // shadeImageについてmultiplyで描画を実行
112
+
71
113
  context.globalCompositeOperation = 'multiply';
72
114
 
73
115
  context.drawImage(shadeImage, 0, 0, width, height);
116
+
117
+
74
118
 
75
119
  if (sources !== SRC_ARR.back &&
76
120
 
77
121
  sources !== SRC_ARR.right &&
78
122
 
79
123
  sources !== SRC_ARR.left) {
124
+
125
+ // 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
126
+
127
+ // そして,次のthenコールバックを発火させるために,resolveを呼び出す
80
128
 
81
129
  loadImageAsync(BTN_FRONT).then(image => {
82
130
 
@@ -96,11 +144,13 @@
96
144
 
97
145
  }
98
146
 
147
+ // 条件を満たさないときは直ちにresolveを呼び出す
148
+
99
149
  resolve();
100
150
 
101
151
  }))
102
152
 
103
- .then(() => console.log('All Finish!!'));
153
+ .then(() => console.log('All Finish!!')); // 最後にここが実行される
104
154
 
105
155
  }
106
156
 

5

Finish修正

2016/07/26 07:07

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -54,7 +54,7 @@
54
54
 
55
55
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
56
56
 
57
- .then(images => {
57
+ .then(images => new Promise(resolve => {
58
58
 
59
59
  const [shadeImage, ...otherImages] = images;
60
60
 
@@ -88,13 +88,19 @@
88
88
 
89
89
  console.log('Draw Finish!');
90
90
 
91
+ resolve();
92
+
91
93
  });
94
+
95
+ return;
92
96
 
93
97
  }
94
98
 
95
- console.log('All Finish!');
99
+ resolve();
96
100
 
97
- });
101
+ }))
102
+
103
+ .then(() => console.log('All Finish!!'));
98
104
 
99
105
  }
100
106
 

4

constつけ忘れた

2016/07/26 06:55

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -56,7 +56,7 @@
56
56
 
57
57
  .then(images => {
58
58
 
59
- [shadeImage, ...otherImages] = images;
59
+ const [shadeImage, ...otherImages] = images;
60
60
 
61
61
  for (const image of otherImages) {
62
62
 

3

case統一

2016/07/26 06:52

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -36,7 +36,7 @@
36
36
 
37
37
 
38
38
 
39
- function synthesizeImage(imageSources, colorSource, shadeSource, canvas_id)
39
+ function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
40
40
 
41
41
  {
42
42
 
@@ -44,7 +44,7 @@
44
44
 
45
45
  const height = 1620;
46
46
 
47
- const context = document.getElementById(canvas_id).getContext('2d');
47
+ const context = document.getElementById(canvasId).getContext('2d');
48
48
 
49
49
  context.clearRect(0, 0, width, height);
50
50
 
@@ -78,7 +78,7 @@
78
78
 
79
79
  sources !== SRC_ARR.left) {
80
80
 
81
- loadImageAsync(btn_front).then(image => {
81
+ loadImageAsync(BTN_FRONT).then(image => {
82
82
 
83
83
  context.globalCompositeOperation = 'source-over';
84
84
 
@@ -99,3 +99,9 @@
99
99
  }
100
100
 
101
101
  ```
102
+
103
+
104
+
105
+ - `btn_front`はグローバル変数のようなので,それと分かるように`SRC_ARR`同様すべて大文字にしました.
106
+
107
+ - 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.

2

ミス

2016/07/26 06:51

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -54,7 +54,9 @@
54
54
 
55
55
  .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
56
56
 
57
+ .then(images => {
58
+
57
- .then((shadeImage, ...otherImages) => {
59
+ [shadeImage, ...otherImages] = images;
58
60
 
59
61
  for (const image of otherImages) {
60
62
 

1

変数名

2016/07/26 06:48

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -18,15 +18,15 @@
18
18
 
19
19
  return new Promise(resolve => {
20
20
 
21
- const img = new Image;
21
+ const image = new Image;
22
22
 
23
- img.src = source;
23
+ image.src = source;
24
24
 
25
- img.addEventListener('load', function self() {
25
+ image.addEventListener('load', function self() {
26
26
 
27
- img.removeEventListener('load', self);
27
+ image.removeEventListener('load', self);
28
28
 
29
- resolve(img);
29
+ resolve(image);
30
30
 
31
31
  });
32
32
 
@@ -36,7 +36,7 @@
36
36
 
37
37
 
38
38
 
39
- function synthesizeImage(sources, color, shade, canvas_id)
39
+ function synthesizeImage(imageSources, colorSource, shadeSource, canvas_id)
40
40
 
41
41
  {
42
42
 
@@ -52,23 +52,23 @@
52
52
 
53
53
  Promise
54
54
 
55
- .all([shade, color, ...sources].map(loadImageAsync))
55
+ .all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
56
56
 
57
- .then((shade, ...images) => {
57
+ .then((shadeImage, ...otherImages) => {
58
58
 
59
- for (const img of images) {
59
+ for (const image of otherImages) {
60
60
 
61
61
  context.globalCompositeOperation = 'source-over';
62
62
 
63
63
  context.globalAlpha = 1.0;
64
64
 
65
- context.drawImage(img, 0, 0, width, height);
65
+ context.drawImage(image, 0, 0, width, height);
66
66
 
67
67
  }
68
68
 
69
69
  context.globalCompositeOperation = 'multiply';
70
70
 
71
- context.drawImage(shade, 0, 0, width, height);
71
+ context.drawImage(shadeImage, 0, 0, width, height);
72
72
 
73
73
  if (sources !== SRC_ARR.back &&
74
74
 
@@ -76,13 +76,13 @@
76
76
 
77
77
  sources !== SRC_ARR.left) {
78
78
 
79
- loadImageAsync(btn_front).then(img => {
79
+ loadImageAsync(btn_front).then(image => {
80
80
 
81
81
  context.globalCompositeOperation = 'source-over';
82
82
 
83
83
  context.globalAlpha = 1.0;
84
84
 
85
- context.drawImage(img, 0, 0, width, height);
85
+ context.drawImage(image, 0, 0, width, height);
86
86
 
87
87
  console.log('Draw Finish!');
88
88