覚えておくべき前提条件
1.実行について
*関数は実行されて初めて処理が始まる
例)
1.Func();--処理が始まる
2.btn.addEventListener()--『ボタンを押して初めて』実行されている
2.キューについて
非同期処理にすることによってメインの処理を待たずに他の関数を実行できる
ただ非同期処理内でも、先入先出しなので、順番は守らなければならない。
3.setTimeoutについて
setTimeout()は
第一引数に処理を、第二引数に待機時間を記入するが
第二引数がないと、コールスタックが吐き切るまで、実行されない
例
function a() {
// 2.コールスタックが全て終了するまで待機
setTimeout(function task1() {
console.log('settimeout done');
});
console.log('fn a done');
}
function b() {
console.log('fn b done');
}
// 1 aが呼ばれる
a();
// 3.setTimeoutはパスして3を実行する
b();
結果
ではコールスタックにあるb()を差し置いてsetTimeoutを実行してからb()を呼ぶにはどうすればいいのか?
b()を道連れにしよう
どういうことかというと
関数b()をコールバックして、setTimeoutの実行中にb()を呼び出すようにする
setTimeout内で実行するのだ。
フロー
1.a(b) bをaのコールバックにしてs
2.b() setTimeoutのコンテキスト内にb()記述し、setTimeoutが実行してから,b()を実行できるようにする
function a(b) {
setTimeout(function task1() {
console.log('task1 done');
b();
});
console.log('fn a done');
}
function b() {
console.log('fn b done');
}
a(b);
// b();
無事修正完了!
2.キュー内で関数をどんどん生成していく方法
function sleep(callback,val){
setTimeout(function(){
console.log(val++);
callback(val);
},1000);
}
sleep(function(val){
sleep(function(val){
},val)
},0)
例
function sleep(callback,val){
setTimeout(function(){
console.log(val++);
callback(val);
},1000);
}
sleep(function(val){
sleep(function(val){
sleep(function(val){
},val)
},val)
},0)
例の解説
関数の実行
// 1.sleep関数が実行されます。
sleep(
//入れ子関数
},0)
//この時の第一引数は入れ子関数で、第二引数は0です
// 2.sleepが実行されるので、先ほど渡した第二引数の0を用いてval『0』に1を追加します
function sleep(callback,val){
setTimeout(function(){
console.log(val++);
},1000);
}
// 3.callback(val)の正体は1.で記述した第一引数の入れ子関数です。先ほど作成したval『1』を引数日して実行していきましょう」。
function sleep(callback,val){
setTimeout(function(){
console.log(val++);
// 3.
callback(val);
},1000);
}
// 4. 3.で入れ子関数を実行しろという命令が出ました。
sleep(function(val){
sleep(function(val){
sleep(function(val){
},val)
},val)
},0)
これをみると1-4をずっと繰り返すことになりますvalはインクリメント(増加)していくので、結果的にvalが入れ子の数だけ増えていくしくみになりました
結論
このコード読みにくくない?!
ということで可読性を向上させるために作成したのが
promiseでした。