ホームページ > 記事 > ウェブフロントエンド > JavaScript のコールバック関数 (同期および非同期) の詳細な分析
コールバック関数は、すべてのフロントエンド プログラマが知っておくべき概念の 1 つです。コールバックは、配列、タイマー関数、Promise、およびイベント処理で使用できます。この記事では、コールバック関数の概念を説明し、同期と非同期の 2 種類のコールバックを区別するのに役立ちます。
まず、人々に挨拶する関数を作成します。
name
パラメーターを受け入れる関数 greet(name)
を作成するだけです。この関数は挨拶メッセージを返す必要があります:
function greet(name) { return `Hello, ${name}!`; } greet('Cristina'); // => 'Hello, Cristina!'
たくさんの人に挨拶したらどうしますか?特別な配列メソッド array.map()
を使用して、次のことを実現できます。
const persons = ['Cristina', 'Ana']; const messages = persons.map(greet); messages; // => ['Hello, Cristina!', 'Hello, Ana!']
persons.map(greet)
すべての persons## を取得します。 # 配列要素を指定し、各要素を呼び出しパラメーターとして使用して
greet() 関数を呼び出します:
`greet('Cristina'),
greet('Ana') 。
persons.map(greet) メソッドは、パラメータとして
greet() 関数を受け入れることができます。このように、
greet() は
コールバック関数 になります。
persons.map(greet) は別の関数をパラメータとして取る関数なので、
高階関数と呼ばれます。
コールバック関数高階関数のパラメータとして、高階関数はコールバック関数を呼び出して演算を実行します。重要なことは、高階関数がコールバックを呼び出し、それに正しいパラメーターを提供する責任があるということです。 前の例では、高階関数
persons.map(greet) が
greet() 関数を呼び出し、その中のすべての要素を変換します。 array
'Cristina' および
Ana ' を引数として使用します。
array.map() メソッドの同等バージョンを次に示します。
function map(array, callback) { const mappedArray = []; for (const item of array) { mappedArray.push( callback(item) ); } return mappedArray; } function greet(name) { return `Hello, ${name}!`; } const persons = ['Cristina', 'Ana']; const messages = map(persons, greet);messages; // => ['Hello, Cristina!', 'Hello, Ana!']
map(array, callback) はコールバックを使用するため、高階関数です。関数をパラメータとして指定し、その本体内でコールバック関数を呼び出します:
callback(item)。
function で定義) またはアロー関数 (太い矢印
=> で定義) もコールバックとして使用できることに注意してください。
同期コールバックと非同期コールバックという 2 つの方法があります。
同期コールバックは「ブロック」されています。コールバック関数が完了するまで、高階関数は実行を継続しません。 たとえば、map() 関数と
greet() 関数を呼び出します。
function map(array, callback) { console.log('map() starts'); const mappedArray = []; for (const item of array) { mappedArray.push(callback(item)) } console.log('map() completed'); return mappedArray; } function greet(name) { console.log('greet() called'); return `Hello, ${name}!`; } const persons = ['Cristina']; map(persons, greet); // logs 'map() starts' // logs 'greet() called' // logs 'map() completed'その中の
greet() は同期コールバックです。
'map() 開始'
最も一般的に使用されるメソッドは配列です。例:
array.map(callback)、array.forEach(callback)
、array.find(コールバック )
, array.filter(callback)
, array.reduce(callback, init)
<pre class="brush:php;toolbar:false">// Examples of synchronous callbacks on arrays
const persons = ['Ana', 'Elena'];
persons.forEach(
function callback(name) { console.log(name);
}
);
// logs 'Ana'
// logs 'Elena'
const nameStartingA = persons.find(
function callback(name) { return name[0].toLowerCase() === 'a';
}
);
nameStartingA; // => 'Ana'
const countStartingA = persons.reduce(
function callback(count, name) { const startsA = name[0].toLowerCase() === 'a';
return startsA ? count + 1 : count;
},
0
);
countStartingA; // => 1</pre>
String type
メソッドは同期的に実行されるコールバックも受け入れることができます: <pre class="brush:php;toolbar:false">// Examples of synchronous callbacks on strings
const person = 'Cristina';
// Replace 'i' with '1'
person.replace(/./g,
function(char) { return char.toLowerCase() === 'i' ? '1' : char;
}
); // => 'Cr1st1na'</pre>
次の例では、
later() 関数の実行が 2 秒遅れます: <pre class="brush:php;toolbar:false">console.log('setTimeout() starts');
setTimeout(function later() {
console.log('later() called');
}, 2000);
console.log('setTimeout() completed');
// logs 'setTimeout() starts'
// logs 'setTimeout() completed'
// logs 'later() called' (after 2 seconds)</pre>
は非同期関数です。 callback、setTimeout(later, 2000)
は実行を開始して完了しますが、later()
は 2 秒後に実行されるためです。 コールバックを非同期で呼び出す手順:
setTimeout(function later() { console.log('2 seconds have passed!'); }, 2000); // After 2 seconds logs '2 seconds have passed!' setInterval(function repeat() { console.log('Every 2 seconds'); }, 2000); // Each 2 seconds logs 'Every 2 seconds!'
DOM イベント リスナーは、イベント処理関数も非同期的に呼び出します (コールバック関数のサブタイプ):
const myButton = document.getElementById('myButton'); myButton.addEventListener('click', function handler() { console.log('Button clicked!'); }); // Logs 'Button clicked!' when the button is clicked4. 非同期コールバック関数と非同期関数
は非同期関数を作成します: <pre class="brush:php;toolbar:false">async function fetchUserNames() {
const resp = await fetch('https://api.github.com/users?per_page=5');
const users = await resp.json();
const names = users.map(({ login }) => login);
console.log(names);
}</pre>
<p><code>fetchUserNames()
是异步的,因为它以 async
为前缀。函数 await fetch('https://api.github.com/users?per_page=5')
从 GitHub 上获取前5个用户 。然后从响应对象中提取 JSON 数据:await resp.json()
。
异步函数是 promise 之上的语法糖。当遇到表达式 await <promise>
(调用 fetch()
会返回一个promise)时,异步函数会暂停执行,直到 promise 被解决。
异步回调函数和异步函数是不同的两个术语。
异步回调函数由高阶函数以非阻塞方式执行。但是异步函数在等待 promise(await <promise>
)解析时会暂停执行。
但是你可以把异步函数用作异步回调!
让我们把异步函数 fetch UserNames()
设为异步回调,只需单击按钮即可调用:
const button = document.getElementById('fetchUsersButton'); button.addEventListener('click', fetchUserNames);
回调是一个可以作为参数传给另一个函数(高阶函数)执行的函数。
回调函数有两种:同步和异步。
同步回调是阻塞的。
异步回调是非阻塞的。
【相关推荐:javascript学习教程】
以上がJavaScript のコールバック関数 (同期および非同期) の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。