はじめに
つい先日(2/3)、AWS LambdaがNode.js 14のサポートを開始しました。
AWS Lambda が Node.js 14 のサポートを開始
Node.js 10が4月末でEOL(新規Lambda作成は3月末くらいまで)になるので、このタイミングでNode.js 14(または12)への移行を検討している人もいるのでは?と思います。
そこで今回は、Node.js 14...というよりは、ES2020仕様(node.js 10ではほとんどが未サポート)で追加された、便利だなと思う新要素をピックアップしてみました。
ちなみに、各種要素のバージョン別サポート状況は、下記サイトで確認できます。
https://node.green/
紹介する新要素
- Promise.allSettled
- nullish coalescing operator (??)
- optional chaining operator (?.)
- (おまけ)CloudFormationでのデプロイ
Promise.allSettled(node.js 12.9.0以降)
これは前々回の【JavaScript】非同期処理(async/await)に関するちょっとしたTips - echo("備忘録");でも紹介した新要素です。
使い方としては下記ソースのようになり、引数の配列に指定した複数のPromiseについて、
というものです。
Promise.all()と似ていますが「rejectされたPromiseがあっても、Promise.allSettled()自体はrejectされない(=エラーにならない)」点が異なります。
Promise.allSettled([...promise]).then(results => {});
具体的には、下記ケースで役に立ちます。
【サンプルソース】
/** * Promise.allSettlednの使用例 */ const main = async () => { const promises = []; for(let i = 0; i <3; i++) { // someFuncAsync()は何か処理を行う非同期処理。 // ただし、処理フロー上rejectされるケースが // 普通に起こりえるとする。 promises.push(someFuncAsync(i)); } // Promise.allSettledで全Promiseを待つ const results = await Promise.allSettled(promises); // ここからが異なる for (let j = 0; j < 3; j++) { // Promise.allSettled()を使用した場合、各promiseの //「status」キーでresolve/rejectを判別可能 // もちろんrejectされても、Promise.allSettled()自体は // rejectされない。(=エラーにならない) if (results[j].status === 'fulfilled') { // statusが'fullfilled'の場合、そのpromiseはresolveされた。 // その場合、resolveされた値はキー「value」に格納される console.info(`someFuncAsync(${j}) はresolveされました。`); console.info(`戻り値: ${results[j].value}`); } else if (results[j].status === 'rejected'){ // statusが'rejected'の場合、そのpromiseはrejectされた。 // その場合、キー「reason」にその理由が格納される console.warn(`someFuncAsync(${j}) はrejectされました。`); console.warn(`理由: ${results[j].reason}`); } } }
nullish coalescing operator (??) (node.js 14.0.0以降)
日本語に訳すと「null合体演算子」(?)
使い方としては、下記ソースのような感じです。
const hoge = fuga ?? piyo;
上記ソースですが、挙動として
- fugaがnullまたはundefinedの場合のみ、??の右の値(piyo)を返す。
- hoge=piyoになる
- fugaがnullでもundefinedでもない場合、??の左の値(fuga)をそのまま返す。
- hoge=fugaになる
となります。
今までこういう場合、下記ソースのように「||」演算子で比較していましたが、「??」は「||」と違い、fugaが空文字、0、falseでもhoge=fugaになるという違いがあります。
というか、この点が非常に大きくて、結構これがバグの原因になったり、制御が厄介だったりしたので、個人的にこの機能の追加追加は本当に嬉しいです。
// 「||」での判定では、fugaが空文字, 0 ,falseだとhoge = piyoになる。 const hoge = fuga || piyo; // 「??」での判定では、fugaが空文字, 0 ,falseでもhoge = fugaになる。 const hoge = fuga || piyo;
optional chaining operator (?.) (node.js 14.0.0以降)
日本語に訳すと「選択的連結演算子」(かな?)
使い方としては、下記ソースのような感じで「nullまたはundefinedになるかもしれない要素、およびその子孫要素にアクセスする」場合に使用します。
const hoge = fuga?.piyo
上記ソースは、下記の挙動となります。
ネストされたオブジェクトへのアクセスに便利
これが便利なのが、上記に書いた通り「ネストされたオブジェクトへのアクセス」で、例えば下記オブジェクト(何かしらのユーザーの指名情報)があったとします。
そして「fullName以降のキーは指定されないケースもある」とします。
const userData = { user: { country: 'USA', fullName: { firstname: 'John', middleName: 'Fitzgerald', familyName : 'Kennedy' } }
この場合に「firstName」にアクセスする場合、今までだと下記のように、親以上の要素のキーについてチェックする必要がありました。
const firstName = (userData.user.fullName && userData.user.fullName.firstName) ? userData.user.fullName.firstName : "No firstName"; // 下記だとfullNameがない場合にエラーになる const firstName = userData.user.fullName.firstName;
しかし今回のoptional chaining operatorを使えば、下記1行でOKになります。
// 下記だとfullNameがなくてもエラーにならない。 // fullNameがない場合、firstNameはundefinedになる。 const firstName = userData.user.fullName?.firstName; // nullish coalescing operatorと組み合わせて、下記書き方もできる。 const firstName = userData.user.fullName?.firstName ?? "No firstName";
(おまけ)CloudFormationでのデプロイについて
AWS Lambdaのランタイムをnode.js 14にしてCloudFormationでデプロイする場合ですが、AWS公式のドキュメントの「Runtime」項目には「node.js 14.x」の記載がありません。
しかし、これは単にドキュメントの修正がまだされてないだけで、Runtimeに「node.js14.x」を指定すれば、問題なくnode.js 14でのデプロイが可能です。
また、Serverless Frameworkでもprovider.runtimeに「node.js14.x」を指定すれば、問題なくnode.js 14でのデプロイが可能です。(下記画像の警告は出ますが、デプロイ自体は問題なし)
まとめ
以上、Node.js 14(てか、ES2020仕様)で便利な機能の紹介でした。
中でもPromise.allSettled()やnullish coalescing operatorなんかは、本当に便利だと思いますので、こういう便利な新機能をどんどん活用していきたいですね。
というか既存機能でも結構知らない機能があったので、node.green なり MDN Web Docs なりでしっかり見直しておかないといけないなあ、と思いました。
告知
3/20(土)に開催される「JAWS DAYS 2021」にて、「AWS Lambdaのテストで役立つ各種ツール」という内容で登壇させていただくことになりました。(諸事情により、タイトル変更しました)
jawsdays2021.jaws-ug.jp
内容としては、1/6(水)の「Serverless Meetup Japan Virtual #14」での登壇内容である「Severless Frameworkで行うLambdaテスト」をベースに、時間の関係でお話しできなかった内容を追加する予定です。
それでは、今回はこの辺で。