非同期プログラミング:コールバック地獄とPromise
53161 ワード
非同期処理とは?
各勘定科目のJavaScriptの非同期処理は、特定のコードの演算が終了するまで、コードの実行を停止するのではなく、まず次のコードのJavaScriptのプロパティを実行することを意味します.
「直接運転開始!
「最後に実行します!」
「2秒後に運転開始!
非同期Web APIであるため、このメソッドは最も遅く実行されます.
このように、特定の論理実行の終了を待たずに、まず残りのコードを実行することが非同期処理である.
なぜ非同期処理が必要なのですか?
1朕は、すべてのことを順次処理する必要がある同期処理について、サーバからデータを受信するコードを最前端に置くとしたら、どうする?
2データ量が大きい場合は?
無限に待つ...
コールバック関数
搦搦コールバック関数は,特定の関数のパラメータとして伝達される関数である.
例
コールバック関数を使用する理由
板橋隊長の例を見てみましょう.
次の例はajax通信を用いてサーバからデータを受信するコードである.
私たちは$です.get()メソッドでhttps://domain.com/から1番商品の情報を取得した後、この情報をtableData変数に割り当てたい.
$.get()メソッドは非同期メソッドなので、最後に実行され、tableDataにundefinedが割り当てられます.
(tableData 1は項目情報を含まない…)
コールバック関数を使用すると、予想される順序で処理できます.
コールバック関数を呼び出してコールバック関数のパラメータにデータを割り当てます.
私たちの最初の意図に従って、私たちはデータを受け取りました!
しかし、コールバック関数の使用には大きな問題があります!
以下はDREAM符号化Ellyのコールバック関数地獄の例である.
コールバック関数地獄が起こったら...
1▼読みづらい=>毒性が低い.
(ビジネスロジックは一目瞭然ではありません)
2πは,エラーやデバッグが必要な場合でも非常に困難である.
△エラーがどこで発生したかを特定するのは難しい.
3」メンテナンスも大変です.
注意:javascript非同期処理の起動コールバックを理解し、コールバック地獄を体験する😱 JavaScript Calback|フロントエンド開発者入門(JavaScript ES 6)
Promise
注意:JavaScript 12。JavaScript Promise|フロントエンド開発者入門(JavaScript ES 6)
ソース:非同期プログラミング|JavaScriptワールド
JS]非同期(async)プログラミングについて[1]。JS非同期モード紹介|by Kwoncheol Shin|Medium
JavaScript非同期処理とコールバック関数•Capacityブリッジ
JavaScript非同期タスクの処理方法
1.同期と非同期、コールバック関数
第2部-JavaScript非同期プログラミング(コールバック、インフラストラクチャ)
各勘定科目のJavaScriptの非同期処理は、特定のコードの演算が終了するまで、コードの実行を停止するのではなく、まず次のコードのJavaScriptのプロパティを実行することを意味します.
console.log("바로 실행됩니다!");
setTimeout(() => {
console.log("2초 뒤에 실행됩니다!");
}, 2000);
console.log("제일 나중에 실행됩니다!");
¥2,000実際の運行結果は:「直接運転開始!
「最後に実行します!」
「2秒後に運転開始!
非同期Web APIであるため、このメソッドは最も遅く実行されます.
このように、特定の論理実行の終了を待たずに、まず残りのコードを実行することが非同期処理である.
なぜ非同期処理が必要なのですか?
1朕は、すべてのことを順次処理する必要がある同期処理について、サーバからデータを受信するコードを最前端に置くとしたら、どうする?
2データ量が大きい場合は?
無限に待つ...
コールバック関数
搦搦コールバック関数は,特定の関数のパラメータとして伝達される関数である.
例
const testCallback = function (callback) {
callback();
};
function callback() {
console.log("this is callback")
}
testCallback(callback);
これにより,関数のパラメータで関数を伝達することができ,このとき伝達される関数をコールバック関数と呼ぶ.コールバック関数を使用する理由
板橋隊長の例を見てみましょう.
次の例はajax通信を用いてサーバからデータを受信するコードである.
私たちは$です.get()メソッドでhttps://domain.com/から1番商品の情報を取得した後、この情報をtableData変数に割り当てたい.
function getData() {
var tableData;
$.get('https://domain.com/products/1', function (response) {
tableData = response;
});
return tableData;
}
console.log(getData()); // undefined
でも….$.get()メソッドは非同期メソッドなので、最後に実行され、tableDataにundefinedが割り当てられます.
(tableData 1は項目情報を含まない…)
コールバック関数を使用すると、予想される順序で処理できます.
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
非同期メソッド$get()実行後にデータを収集します.コールバック関数を呼び出してコールバック関数のパラメータにデータを割り当てます.
私たちの最初の意図に従って、私たちはデータを受け取りました!
しかし、コールバック関数の使用には大きな問題があります!
以下はDREAM符号化Ellyのコールバック関数地獄の例である.
console.log(1);
setTimeout(function () {
console.log(2);
}, 1000);
console.log(3);
// 동기 콜백
const printImmediately = function (print) {
print();
};
printImmediately(() => { console.log('hello world!') });
// 비동기 콜백
const printWithDelay = function (print, delay) {
setTimeout(print, delay);
}
printWithDelay(() => { console.log('hello world!') }, 2000);
// callback hell example
class UserStorage {
loginUser(id, password, onSuccess, onError) {
setTimeout(() => {
if (
(id === "ellie" && password === "dream") ||
(id === "coder" && password === "academy")
) {
onSuccess(id);
} else {
onError(new Error("not found!"));
}
}, 2000);
}
getRoles(user, onSuccess, onError) {
setTimeout(() => {
if (user === "ellie") {
onSuccess( {name: "ellie", role: "admin"} );
} else {
onError(new Error("no Sucees!"));
}
}, 1000);
}
getPart(role, onSuccess, onError) {
setTimeout(() => {
if (role === "admin") {
onSuccess ( {part: "develop"} );
} else {
onError(new Error("no Success!"));
}
}, 3000);
}
}
const userStorage = new UserStorage();
const id = prompt("enter your id");
const password = prompt("enter your password");
userStorage.loginUser(
id,
password,
(user) => {
userStorage.getRoles(
user,
(userWithRoles) => {
alert(`Hello! ${userWithRoles.name}, you have a ${userWithRoles.role} role!`);
userStorage.getPart(
userWithRoles.role,
(userWithPart) => {
alert(`Your part is ${userWithPart.part}!`);
},
(error) => {
console.log(error);
}
)
},
(error) => {
console.log(error);
}
);
},
(error) => {
console.log(error);
}
);
⑪callback関数の問題コールバック関数地獄が起こったら...
1▼読みづらい=>毒性が低い.
(ビジネスロジックは一目瞭然ではありません)
2πは,エラーやデバッグが必要な場合でも非常に困難である.
△エラーがどこで発生したかを特定するのは難しい.
3」メンテナンスも大変です.
Promise
'use strict';
// Promise is JavaScript object for asynchronous operation.
// State : panding -> fulfilled or rejected
// Producer vs Consumer.
// 1. Producer
const id = "ellie";
// doing some Heavy work (ex. network, read files)
const promise = new Promise((resolve, reject) => {
// when new Promise is created, the excutor runs automatically.
// promise 를 만들자마자 기능을 수행해버림 (익스큐터라는 콜백함수가 바로 실행되버림).
// 만약 사용자가 버튼을 누른 순간부터 기능을 수행하고 싶다면? => ??
console.log('doing something!');
if (id === "ellie") {
setTimeout(() => {
resolve('ellie');
}, 2000);
} else {
setTimeout(() => {
reject(new Error('no network!'));
}, 3000)
}
});
// 2. Consumer : then, catch, finally
promise
.then((value) => {
console.log(value);
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log("end!");
})
// 3. Promise chaining.
const fetchNumber = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
// then은 값을 바로 전달할 수도 있고, promise를 전달할 수 도 있다.
fetchNumber
.then((num) => num * 2)
.then((num) => num * 3)
.then((num) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num - 1);
}, 1000);
});
})
.then((num) => console.log(num));
// 4. Error Handling.
const getHen = () => {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('🐓') }, 1000);
});
};
const getEgg = (hen) => {
return new Promise((resolve, reject) => {
setTimeout(() => { reject(new Error(`${hen} => 🥚`)) }, 1000);
});
};
const cook = (egg) => {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve(`${egg} => 🍳`) }, 1000);
});
};
// getHen()
// .then(hen => getEgg(hen))
// .then(egg => cook(egg))
// .then(meal => console.log(meal));
getHen() //
.then(getEgg)
.catch(error => {
return '🥖';
})
.then(cook)
.then(console.log);
DREAM符号化EllyのPromise講義コードconst id = prompt('enter your id');
const password = prompt('enter your password');
const takeUserId = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (
(id === 'ellie' && password === 'dream') ||
(id === 'coder' && password === 'academy')
) {
resolve(id);
} else {
reject(new Error('input correct "id" or "password"!'));
}
}, 1000);
});
};
const takeUserRole = (userId) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userId === "ellie") {
const userRole = "admin";
resolve(userRole);
} else if (userId === "coder") {
const userRole = "play";
resolve(userRole);
} else {
reject(new Error('Cant find user role!'));
}
}, 1000);
});
};
const takeUserPart = (userRole) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userRole === "admin" || userRole === "play") {
const userPart = 'development';
resolve(console.log(`Your part is ${userPart}!`));
} else {
reject(new Error('dont find your role!'));
}
}, 1000);
});
};
takeUserId() //
.then(takeUserRole)
.then(takeUserPart);
プロミスを用いて,以前の例のコールバック地獄の様子を解決した.注意:JavaScript 12。JavaScript Promise|フロントエンド開発者入門(JavaScript ES 6)
ソース:非同期プログラミング|JavaScriptワールド
JS]非同期(async)プログラミングについて[1]。JS非同期モード紹介|by Kwoncheol Shin|Medium
JavaScript非同期処理とコールバック関数•Capacityブリッジ
JavaScript非同期タスクの処理方法
1.同期と非同期、コールバック関数
第2部-JavaScript非同期プログラミング(コールバック、インフラストラクチャ)
Reference
この問題について(非同期プログラミング:コールバック地獄とPromise), 我々は、より多くの情報をここで見つけました https://velog.io/@effort_jk/비동기-프로그래밍テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol