LoginSignup
0
0

More than 3 years have passed since last update.

Google Sheet API(Node.js利用)で、複数シートを順番に生成できずハマったので、解決コードを晒してみる

Last updated at Posted at 2021-03-01

Google Sheet API(Node.js利用)で、複数のシートを「1,2,3,4...」と並べて生成したいのに、
async,awaitで生成しても、シートが2,4,3,1みたいに順不同になってしまうのを、
どう回避できるかなかなかわかりませんでした。

辿り着いた解決策は、
array.reduceとPromiseを組み合わせて、thenでつないでいき、
Promise内でsetTimeoutをする、というものでした。

reduceに慣れていなかったので、
各引数の理解(特に第1とinitialValue)と、thenの理解、
また、初期値にPromice.resolve()を渡すあたりが難しかったです。

以下、実際に動くようになったコードです。
(SheetAPIのラッパークラスを自作していますので、よしなに読み替えてください)

import {Sheet} from './Sheet.mjs'//シート関連の処理を集めた自作クラス
import dotenv from 'dotenv'
dotenv.config()

const spreadsheetId = process.env.SOME_SPREADSHEET_ID

/**
 * 複数のシートを順番に作成する
 */
const main = async function() {
  const sheet = await Sheet.build()//auth取得などはここで処理している
  //複数シート作成のため連番を準備(スプレッド構文便利ね)
  const arr = [...(Array(10).keys())].slice(1)//0は排除

  //関数の中でPromiseオブジェクトを返す無名関数を準備。これをarr.reduceで逐次実行する
  const createWithSleep = (sheetName) => {
    return () => {//ここで無名関数化してPromiseを返すのがreduce.then実行のキモ。無いと動かなかった
      return new Promise(resolve => {
        setTimeout(()=>{
          createSheet(sheetName, sheet)//シート生成メソッド呼び出し
          resolve()//resolve()でreduce内のthenが発火
        }, 2000)//thenで実行していても、一定の時間差がシート順次生成に必要!500などではだめだった
      })
    }
  }

  //ここのarr.reduceでの逐次実行がとても重要!これがないとシートの生成が順不同になる(thenでの処理実行チェーン)
  //シート名は's2'などでは読み取りなどのAPI実行時にカラム名と間違えられ困ったので、'組'というダブルバイトにしている
  arr.reduce((pre, cur) => pre.then(createWithSleep('' + cur)), 
    Promise.resolve())//最初にthenを発火させるために空のPromise.resolve()をinitialValueとして配置
}

//シートの生成部分. setTimeoutで十分時間をとっているのでasync,awaitは設定せず
const createSheet = (sheetName, sheet) => {
  //ここのcreateSheetは普通のAPIメソッドの単なるラッパーです
  sheet.createSheet(sheetName, spreadsheetId).then(() => console.log('created'))
}

main()

Google Sheet APIは、サクッとspreadsheetを作れたり、値を書き込んだり読み込んだり、
sheetを作成したり、超便利ですね。
nodeでローカルから楽しく操作できるのが気に入りましたが、
ちょいちょい書き方に詰まったので、同じところで詰まった方に役に立てばと、
恥を忍んでコードを晒してみます。

どなたかのお役に立てば幸いにて。
ではでは。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0