🙂

Promiseチェーンを可変長にする方法

2024/09/07に公開

背景

Promiseチェーンは複数の非同期処理を順番に実行するための方法である。
例えば、以下のようなコードのことを指す。

const promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("First"), 1000);
});

promise
    .then(result => {
        console.log(result); // "First"
        return "Second";
    })
    .then(result => {
        console.log(result); // "Second"
        return "Third";
    })
    .then(result => {
        console.log(result); // "Third"
    });

この例では、1000ms後に「First」が出力され、その後「Second」、「Third」の順で出力される。
さらに処理を続けたい場合は、then()メソッドを追加する必要がある。

しかし、この方法ではthen()メソッドの数が固定されているため、任意の長さのチェーンには対応できない。可変長のPromiseチェーンを扱いたい場合、どうすればよいだろうか?

結論

reduceを使うことで、Promiseチェーンを可変長にすることができる。

以下のコードは、then()メソッドで繋げたい処理を配列に格納し、それをreduceを使って処理する例である。

const tasks = [
    () => new Promise(resolve => setTimeout(() => resolve("First"), 1000)),
    () => new Promise(resolve => setTimeout(() => resolve("Second"), 1000)),
    () => new Promise(resolve => setTimeout(() => resolve("Third"), 1000))
];

tasks.reduce(
    (prev, cur) => prev.then(cur).then(result => console.log(result)),
    Promise.resolve()
).then(() => console.log("All completed"));

このreduceの処理によって、以下のようなPromiseチェーンが生成される。
この方法を使えば、任意の数だけPromiseチェーンを繋ぐことが可能となる。

Promise.resolve()
    .then(() => new Promise(resolve => setTimeout(() => resolve("First"), 1000)))
    .then(result => console.log(result))
    .then(() => new Promise(resolve => setTimeout(() => resolve("Second"), 1000)))
    .then(result => console.log(result))
    .then(() => new Promise(resolve => setTimeout(() => resolve("Third"), 1000)))
    .then(result => console.log(result))
    .then(() => console.log("All completed"));

まとめ

reduceを使ってPromiseチェーンを可変長にする方法を紹介した。
この方法を使えば、任意の数だけPromiseチェーンを繋ぐことができる。

Discussion