JavaScriptで非同期処理を実装するPromiseオブジェクトにおいて、複数の非同期処理を順番に処理する方法(Promiseのみ)

JavaScriptで複数の非同期処理を想定した順番に処理させたい(直列処理)

JavaScriptで複数の非同期処理を想定した順番に処理させたい(直列処理)場合があります。

処理が終わった後に、次の処理をつなげる必要がある処理に使われます。

例えば、外部のデータを取得して、そのデータを使って処理を行う必要がある場合は外部データの取得を先にする必要があります。

そういった場合に、この書き方は役立ちます。

処理方法は2つあります。

  • Promiseのみで実装する方法
  • await・acyncを使って実装する方法

この記事ではPromiseのみで実装する方法について紹介していきます。

オブジェクト

オブジェクト意味返り値
new Promise(関数)Promiseを作成するPromiseインスタンス
resolve(引数)Promiseインスタンス内で利用され、非同期処理の終了(成功)を宣言するメソッド。Promiseインスタンス.then(関数)の関数に対して引数の値を渡すことができる。なし
reject(引数)Promiseインスタンス内で利用され、非同期処理の終了(失敗)を宣言するメソッド。Promiseインスタンス.catch(関数)の関数に対して引数の値を渡すことができる。なし
Promiseインスタンス.then(関数)成功した時のコールバック関数を呼び出し実行Promise
Promiseインスタンス.catch(関数)失敗した時のコールバック関数を呼び出し実行Promise
Promise.all(配列)複数のPromiseを並列に実行するPromise
Promiseオブジェクトの仕様

サンプルコード

Promiseのみで直列処理を行うにはPromiseインスタンスを呼び出して1つ目の処理を行った後に、promiseインスタンス.then()メソッドを重ねがけする必要があります。

それを踏まえたサンプルコードを紹介します。想定した順番で5秒ごとに処理を1つ行っています。

Output
処理履歴
Pug
table.table
			tbody
				tr
					th 処理履歴
					td#targetText
JavaScript
const targetText = document.getElementById("targetText");

//Promiseインスタンスの宣言
const promise = new Promise(targetPromiseFunction);

//Promise処理を行う
function targetPromiseFunction( resolve ) {
	let additionalElement = document.createElement("div");
	additionalElement.textContent = `1つ目のPromise ${new Date().toLocaleTimeString()}`;
	targetText.appendChild(additionalElement);
	resolve();
}

promise.then( () => {
	new Promise((resolve) => {
		setTimeout(() => {
			let additionalElement = document.createElement("div");
			additionalElement.textContent = `2つ目のPromise ${new Date().toLocaleTimeString()}`;
			targetText.appendChild(additionalElement);
			resolve();
		}, 5000);
	});
}).then(()=> {
	new Promise((resolve) => {
		setTimeout(() => {
			let additionalElement = document.createElement("div");
			additionalElement.textContent = `3つ目のPromise ${new Date().toLocaleTimeString()}`;
			targetText.appendChild(additionalElement);
			resolve();
		}, 1000);
	});
}).then(()=> {
	new Promise((resolve) => {
		setTimeout(() => {
			let additionalElement = document.createElement("div");
			additionalElement.textContent = `4つ目のPromise ${new Date().toLocaleTimeString()}`;
			targetText.appendChild(additionalElement);
			resolve();
		}, 1000);
	});
});
インストラクター