CSS&JS/👀Study and Copy

[별코딩]Promise.all .allSettled .any .race 예제로 비교하기

arancia_ 2024. 1. 3. 11:47

데모

See the Pen promise예제 by Oh Ikmyeong (@dpffpself) on CodePen.

별코딩 강의 영상

 

html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html>
<head lang="ko">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>자바스크립트 비동기 프로그래밍 #3.5 | Promise.all + allSettled + any + race</title>
    <link rel="stylesheet" href="./style.css" type="text/css">
    <script src="./main.js" type="module"></script>
</head>
<body>
    <a href="https://www.youtube.com/watch?v=0yR_Im3VPqQ&t=513s" target="_blank">별코딩 : 자바스크립트 비동기 프로그래밍 #3.5 | Promise.all + allSettled + any + race</a>
    <p>콘솔창을 확인해보세요</p>
    <p>함수들은 각각 1,2,3초가 걸립니다.</p>
    <div class="btn-wrap">
        <button class="btn" id="btn-all">Promise.all</button>
        <button class="btn" id="btn-all-settled">Promise.allSettled</button>
        <button class="btn" id="btn-any">Promise.any</button>
        <button class="btn" id="btn-race">Promise.race</button>
    </div>
 
    <div id="result"></div>
 
    <div id="timer"></div>
</body>
</html>
cs

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
@charset "utf-8";
*{margin:0;padding:0;box-sizing:border-box;}
 
html,body{min-height:100vh;}
 
body{
    display:flex;flex-flow:column nowrap;
    justify-content:center; align-items:center;
    gap:20px;
}
 
a{
    text-decoration:none;
    font-size:13px;color:inherit;
}
 
.btn-wrap{
    display:flex;flex-flow:row wrap;
    justify-content:center; align-items:center;
    gap:10px;
    position:relative;
}
 
button{
    padding:.5em 1em;
    font-size:inherit;font-family:inherit;
}
 
#result{
    display:flex;flex-flow:row wrap;
    align-items:center;
    gap:10px;
    position:relative;
    width:100%; max-width:800px;
    padding:20px;
    background:#fafafa;
    border:1px solid #dedede; border-radius:4px;
    line-height:1.5;
}
 
#result.success{
    background:#e1ffd9;
    border-color:#059e32;
}
 
#result.fail{
    background:rgb(255, 210, 210);
    border-color:red;
}
 
#result div{
    width:100%;
    padding:1em 10px;
    padding-top:0;
    border-bottom:1px solid rgba(0,0,0,.5);
    font-size:13px;
    line-height:1.6;
}
 
#result p{
    width:100%;
    padding:10px 20px;
    background:#fff;
    border-radius:4px;
    border:1px solid #ccc;
    box-shadow:2px 2px 0 2px rgba(0,0,0,.05);
}
 
#result p.success{
    background:rgb(244, 255, 244);
    border-color:green;
}
 
#result p.fail{
    background:rgb(255, 243, 243);
    border-color:red;
}
 
#timer{
    position:relative;
    padding:5px 10px;
    background:#000;
    border-radius:4px;
    font-size:12px; color:#fff; font-weight:bold;
}
#timer::before{
    content:"소요시간 : "
}
cs

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
const $result= document.getElementById('result');
const $timer = document.getElementById('timer');
let timeStarted;
 
document.getElementsByClassName('btn-wrap')[0].addEventListener('click',(e)=>{
    on_ready_result();
    reset_timer();
    timeStarted = new Date().getTime();
 
    switch(e.target.id){
        case "btn-all" : {
            promise_all();
        }break;
        case "btn-all-settled" : {
            promise_all_settled();
        }break;
        case "btn-any" : {
            promise_any();
        }break;
        case "btn-race" : {
            promise_race();
        }break;
    }
});
 
/* ---------------------------- */
 
function func_1(isSuccess){
    $result.innerHTML += `<span>(1):<strong>${isSuccess ? "✔" : "❌"}</strong></span>`
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            if(isSuccess){
                res("1")
            }else{
                rej(new Error("1"))
            }
        }, 1000);
    });
}//func_1
 
function func_2(isSuccess){
    $result.innerHTML += `<span>(2):<strong>${isSuccess ? "✔" : "❌"}</strong></span>`
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            if(isSuccess){
                res("2")
            }else{
                rej(new Error("2"))
            }
        }, 2000);
    });
}//func_2
 
function func_3(isSuccess){
    $result.innerHTML += `<span>(3):<strong>${isSuccess ? "✔" : "❌"}</strong></span>`
    return new Promise((res,rej)=>{
        setTimeout(()=>{
            if(isSuccess){
                res("3")
            }else{
                rej(new Error("3"))
            }
        }, 3000);
    });
}//func_3
 
/* ---------------------------- */
 
function get_success_list(){
    const sList = [];
    while(sList.length < 3){
        const bool = parseInt(Math.random() * 10>= 5;
        sList.push(bool);
    }
    console.log(sList);
    return sList;
}//get_success_list
 
/* ---------------------------- */
 
function on_ready_result(){
    $result.innerHTML = "";
    $result.classList.remove('success');
    $result.classList.remove('fail');
}//on_ready_result
 
function on_success_result(){
    $result.classList.add('success');
}//on_success_result
 
function on_fail_result(){
    $result.classList.add('fail');
}//on_fail_result
 
/* ---------------------------- */
 
function reset_timer(){
    $timer.innerHTML = "";
}//reset_timer
 
 
function display_time(){
    const timeCurr = new Date().getTime();
    const timeRemain = ((timeCurr - timeStarted) / 1000).toFixed(2);
    $timer.innerHTML = `${timeRemain} 초`
}//display_time
 
 
/* ---------------------------- */
 
 
function display_success(result){
    console.log(result);
    on_success_result();
 
    if(!Array.isArray(result)){ 
        $result.innerHTML += `<p>${result}</p>`; 
        return;
    }
 
    for(const item of result){
        if(typeof item == "string"){
            $result.innerHTML += `<class="success">${item}</p>`;
        }else{
            const {status,value,reason} = item;
            $result.innerHTML += `<class="${status === "fulfilled" ? "success" : "fail"}">status : ${status}, value : ${value}, reason : ${reason}</p>`
        }
    }//for
}//display_success
 
function display_fail(result){
    console.log(result);
    on_fail_result();
 
    $result.innerHTML += `<class="fail">${result}</p>`;
}//display_fail
 
/* ---------------------------- */
function promise_all(){
    $result.innerHTML += "<div>Promise.all : 전부 기다리고, 모두 fulfilled 되어야만 then. 앞의 요소들이 rejected되면 catch로 바로 넘어감</div>";
    const [a,b,c] = get_success_list();
    Promise.all([func_1(a),func_2(b),func_3(c)])
    .then(display_success)
    .catch(display_fail)
    .finally(()=>{
        display_time();
    })
}//promise_all
 
function promise_all_settled(){
    $result.innerHTML += "<div>Promise.all :전부 기다리고, fulfilled,rejected 가리지 않고 모든 사항과 이유에 대해 then으로 전달.</div>";
    const [a,b,c] = get_success_list();
    Promise.allSettled([func_1(a),func_2(b),func_3(c)])
    .then(display_success)
    .catch(display_fail)
    .finally(()=>{
        display_time();
    })
}//promise_all_settled
 
function promise_any(){
    $result.innerHTML += "<div>Promise.any:모든 요소중 하나라도 fulfilled되면 then</div>";
    const [a,b,c] = get_success_list();
    Promise.any([func_1(a),func_2(b),func_3(c)])
    .then(display_success)
    .catch(display_fail)
    .finally(()=>{
        display_time();
    })
}//promise_any
 
function promise_race(){
    $result.innerHTML += "<div>Promise.race:모든 요소중 제일 먼저 fulfilled 된거. 하지만 첫번째 요소가 rejected 되었다면 catch로 넘어감.</div>";
    const [a,b,c] = get_success_list();
    Promise.race([func_1(a),func_2(b),func_3(c)])
    .then(display_success)
    .catch(display_fail)
    .finally(()=>{
        display_time();
    })
}//promise_race
cs