忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

JavaScript Promiseの使い方(非同期処理に関連して)

Promise は、JavaScript において、非同期処理のコールバック関数をより分かりやすく記述するための仕組みです。

非同期処理のコールバック関数の説明のため以下の様な関数があるとします。

■コールバック関数の説明のための例

function test_callback(timeoutval, callback_func) {
	setTimeout(() => { 
	    callback_func();
	}, timeoutval);
}

この関数は時間を待った後で指定コールバック関数の実行するものです。
これを実際に使う場合は以下の様になります。

// 非同期関数を用いて
test_callback(1000, function() {
    console.log('callback...1000');
});

1000msec待って、「callback...1000」をデベロッパーツールのコンソールに出力されます。

■Promiseを使って上記の例を書き変えてみる

先ずはPromiseの説明ですが、Promiseオブジェクトの生成には2個関数の引数を持った関数を渡します。
以下の説明では2個の関数の引数名として「resolve」「reject」としていますが、 それぞれがPromise渡される関数内で処理成功時と失敗時の処理を行う関数を指定します。

引数関数の名前が「resolve」「reject」ですが、別にこの名前ではなくても他のものでも問題ありません。
また、「resolve」のみでもOKです。

// Promiseの生成
const Promise = new Promise((resolve, reject) => {
    // ここで何かの処理
	// …

    if ( [成功]/[失敗]の判定 ) {
        resolve("OK");	// [成功]
    } else {
        reject("NG");	// [失敗]
    }
});

// Promiseの実行
Promise.then((result) => {
	// 成功時は「resolve」から渡されるものが「result」に返される
	console.log(result);	// "OK"が表示される
})
.catch((error) => {
	// 失敗時は「reject」から渡されるものが「error」に返される
	console.log(error);		// "NG"が表示される
});

上記のことを踏まえて、最初のコールバック関数の例を以下の様にします。

function test_callback2(timeoutval) {
    return new Promise((resolve) {
        setTimeout(function() {
            resolve(timeoutval);	// 成功時の関数をコール
        }, timeoutval);
    });
}

これを実行するために以下の様にします。

test_callback2(1000).then((result) => {
    console.log('callback...' + result);
});

結果コンソールには、1000msec待ってから「callback...1000」が出力されます。

結果的には Promise を使ってもさほど違いはありませんが、 最初の例の関数を、コールバック後の処理を繰り返したい場合に以下の様な記述になります。

// コールバック関数のネストが深い!!
test_callback(1000, function() {
    console.log('callback...1000');
    test_callback(2000, function() {
        console.log('callback...2000');
	    test_callback(3000, function() {
	        console.log('callback...3000');
	    });
    });
});

1000msec待って「callback...1000」がコンソールに出力され、 その後、2000msec待って「callback...2000」が、さらに3000msec待って「callback...3000」が出力されます。

この感じではネストが深くなり、ソースが見にくいと思います。 これを解消する為に上記の Promise を使った関数を使用します。

■Promiseを使った処理の連結の例

// コールバック用の関数を再掲
function test_callback2(timeoutval) {
    return new Promise((resolve) {
        setTimeout(function() {
            resolve(timeoutval);	// 成功時の関数をコール
        }, timeoutval);
    });
}

// then で連結する
test_callback2(1000).then((result) => {
    console.log('callback...' + result);
    return test_callback2(2000);
}).then((result) => {
    console.log('callback...' + result);
    return test_callback2(3000);
}).then((result) => {
    console.log('callback...' + result);
});

最初の test_callback2 の then では成功時の処理を書きますが、コンソール出力後 再度、 test_callback2 を実行し、結果を return しています。 よって、この then の結果では return で Promise オブジェクトが返されてくるので さらに then で成功時の処理を書きます。
こうやって順次 then で結合することで、ネストが深くなることを防ぐことができます。
また、順次処理を行うことができます。


関連する記事

JavaScript 何に使う
JavaScript jQueryの使い方(セレクタ)
JavaScript jQueryの使い方(セレクタ)その2
JavaScript 関数の宣言について(function)
JavaScript jQueryでJavascriptファイルの動的に変更する方法
JavaScript jQueryを使った checkbox の操作方法












PR

コメント

コメントを書く