Callback


1.同期と非同期


JavaScript is synchronous!
🔥 JavaScriptは同期化されています🔥
吊り下げから、コード作成順に同期して実行します.
昇格:varとは、関数宣言が自動的に上部に上昇することを意味します.
console.log('1');
// browser에게 요청하고 결과 값을 받는다. - 비동기적 방식
setTimeout(() => console.log('2'), 1000); // 지정한 시간이 지나면 콜백함수 호출
console.log('3');

// 위 처럼 작성시 console에는
1
3
2
// 순으로 나타나게 된다.

2.コールバック関数も2つに分類

// Synchronous callback 
function printImmediately(print) {
  print();
}
printImmediately(() => console.log('hello'));

// Asynchronous callback
function printWithDelay(print, timeout) {
  setTimeout(print, timeout);
}
printWithDelay(() => console.log('async callback'), 2000);

3.カルバック地獄体験


callbackは役に立ちますが、callback地獄を作成することもできます.
class UserStorage {
  loginUser(id, password, onSuccess, onError) {
    setTimeout(() => {
      if (
        (id === 'lee' && password === 'ju' ||
        (id === 'hwan' && password === 'wow')
      ) {
        onSuccess(id);
      } else {
        onError(new Error('not found'));
      }
    }, 2000);
  }
  
  getRoles(user, onSuccess, onError) {
    setTimeout(() => {
      if (user === 'lee') {
        onSuccess({ name: 'lee', role: 'admin' });
      } else {
        onError(new Error('no access'));
      }
    }, 1000);
  }
}
必要な論理
1.ユーザーに「id」「password」と入力します.
2.サーバに入力した情報を送信してログインします.
3.受信したidリクエストロールを使用します.
4.ロール出力を受け入れます.
const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your passrod');
userStorage.loginUser(
  id,
  password,
  user => {
    userStorage.getRoles(
      user,
      userWithRole => {
        alert(
          `Hello ${userWithRole.name}, you have a ${userWithRole.role} role`
        );
      },
      error => {
        console.log(error);
      }
    );
  },
  error => {
    console.log(error);
  }
);

4.ダイヤルバックチェーンの問題点

  • 毒性が低すぎる.
  • デバッグ、メンテナンスが難しい.
  • 5.Promiseで

    class UserStorage {
      loginUser(id, password) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            if (
              (id === 'ellie' && password === 'dream') ||
              (id === 'coder' && password === 'academy')
            ) {
              resolve(id);
            } else {
              reject(new Error('not found'));
            }
          }, 2000);
        });
      }
    
      getRoles(user) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            if (user === 'ellie') {
              resolve({ name: 'ellie', role: 'admin' });
            } else {
              reject(new Error('no access'));
            }
          }, 1000);
        });
      }
      
    const userStorage = new UserStorage();
    const id = prompt('enter your id');
    const password = prompt('enter your passrod');
    userStorage
      .loginUser(id, password)
      .then(userStorage.getRoles)
      .then(user => alert(`Hello ${user.name}, you have a ${user.role} role`))
      .catch(console.log);
    ソース
    非同期処理の起動コールバックについて