質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Chrome extension

Chrome拡張機能

Q&A

2回答

16068閲覧

async/awaitでasync functionのfunctionに対してunexpected tokenのエラーがでる

TarouKotani

総合スコア42

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Chrome extension

Chrome拡張機能

0グッド

0クリップ

投稿2018/03/08 05:47

firebaseを利用したサーバサイドの開発をしており、非同期処理を同期的に直す過程でエラーが出ました。

データをajaxで受け取る→それをfirebaseのデータベースと突合→合致する場合はresponse(500)を帰す
というバックエンドの処理をしようとしています。

「データを格納→完了後に突合」としたく、async/awaitの非同期処理の最後の例にならって、
promise,async,awaitを用いた非同期処理の待ちを実装しましたが、下記のエラーが出ます。

65:9 error Parsing error: Unexpected token function

node.js

1/////////////////////////////////////////index.js////////////////////////////////// 2 3const functions = require('firebase-functions'); 4// // Create and Deploy Your First Cloud Functions 5// // https://firebase.google.com/docs/functions/write-firebase-functions 6// The Firebase Admin SDK to access the Firebase Realtime Database. 7 8// Import Admin SDK 9const admin = require('firebase-admin'); 10admin.initializeApp(functions.config().firebase); 11 12// Get a database reference to our posts 13var db = admin.database(); 14var ref = db.ref("/product"); 15 16//chromeExtensionからのデータを受信 17exports.product = functions.https.onRequest((request, response) => { 18 //POSTを受けると発火 19 if (request.method === "POST") { 20 const body = request.body; 21 const pushRef = admin.database().ref("/product").push(); 22 pushRef.set({ 23 //薬処方時のデータ 24 patientId: body["patientId"], 25 doctor: body["doctor"], 26 idisease: body["idisease"], 27 medicine: body["medicine"], 28 medicineID:body["medicineID"], 29 }, error => { 30 if (error) { 31 console.log("save error", error.message); 32 } else { 33 console.log("save Success!!"); 34 } 35 } 36 ); 37 }//ajaxの受け取り 38 39////////////////////////////////////////////////////////////////////  問題個所はここ以降 40 //medicineIDを薬マスタと突合 41 42 //薬のIDを配列に格納 43 function getInMedId() { 44 const p = new Promise((resolve,reject) => { 45 var inMedId = body.medicineID; 46 resolve(inMedId); 47 }); 48 return p; 49 } 50 51 //マスター側の薬のIDを配列に格納 52 function getPreMedId() { 53 const q = new Promise((resolve,reject) => { 54 var preMedId = []; 55 for(j=0; j<(90+1); j++){ 56 var m = db.ref("/"+j+"/medicineId"); 57 m.on("value", function(snapshot){ 58 preMedId = snapshot.val(); 59 }); 60 } 61 resolve(preMedId); 62 }); 63 return q; 64 } 65 66 //薬のIDを突合 67 async function checkMedId() { <============================================ ※エラー箇所※ 68 for(i=0; i<inMedId.length+1; i++){ 69 for(j=0; j<(90+1); j++){ 70 var a = await getInMedId(); 71 var b = await getPreMedId(); 72 if(a[0][i] === b[j]){ 73 console.log('This medicine is skeptical:'+a); 74 response.status(500).send(error.message).end(); 75 } 76 } 77 } 78 } 79 checkMedId(); 80 //for回して無事だったら普通のレスポンス 81 response.status(200).end(); 82 83}) 84

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

というか、そもそも構文エラーで質問する以前の問題です。
インデントもぐちゃぐちゃなのでまずはESLint等を導入してエラーを取り除いてください。
正しく括弧や波括弧の整合性があってるのか確認してください。

もしコードが正しければNode.jsのバージョンが古い可能性があります。
http://node.green/#ES2017-features-async-functions

async / awaitはバージョン7.10以降に実装された書き方ですので、
下記のコマンドでNode.jsのバージョンを確認し、古ければ新しいバージョンをインストールしてください。
基本的にECMAScriptは下位互換を強く意識しているので、酷いバグでも無い限り出来るだけ最新を入れたほうが良いです。

Bash

1$ node -v

さて、コードが動くようになれば恐らく次の問題が出てくるでしょう。
なので先受けして書いておきます。
(今回のエラーはあくまで構文エラーなので、asyncがどうのとかそういう以前の問題です)

async function () {}を同期処理と勘違いしていませんか?
この形式で書かれた場合、必ずPromiseが戻り値になります。

もしreturn 123;というに正常終了していれば、resolve(123)が実行された事になります。
throw new Error('エラー理由')という風に例外を投げれば、reject(new Error('エラー理由'))が実行された事になります。

つまり、構文の上で取り繕うだけで、
いくら取り繕ったとしても非同期は非同期であり、単なるPromiseです。


これを元にコードを見ていきましょう。

//薬のIDを突合 async function checkMedId() { for(i=0; i<inMedId.length+1; i++){ for(j=0; j<(90+1); j++){ var a = await getInMedId(); var b = await getPreMedId(); if(a[0][i] === b[j]){ console.log('This medicine is skeptical:'+a); response.status(500).send(error.message).end(); } } } } checkMedId(); //for回して無事だったら普通のレスポンス response.status(200).end();

まずcheckMedId()が実行されます。
中身はPromiseな上二重ループの中で何度もawait getInMedId()等が呼ばれているので、
非同期でありその場での処理を諦めています。

なのでどうあがこうが先にresponse.status(200).end();が叩かれ、ステータスコード200が確約されます。
その後、checkMedId内の変数aとbが確定され、response.status(500).send(error.message).end();を実行しようとします。
それ以前にerrorが宣言されてませんが

これはExpressですか?
Expressはステータスコードを二重に宣言しようとしたり、.end後になにかを返そうとすればエラーになります。
こういった流れでエラーが発生しているようです。

ではどうすればよかったのか。
Promiseを叩いて受けるようにコードを修正しましょう。

JavaScript

1 // 薬のIDを突合 2 async function checkMedId() { 3 for(i=0; i<inMedId.length+1; i++){ 4 for(j=0; j<(90+1); j++){ 5 var a = await getInMedId(); 6 var b = await getPreMedId(); 7 if(a[0][i] === b[j]){ 8 throw new Error('This medicine is skeptical:' + a) 9 } 10 } 11 } 12 } 13 // 普通のPromiseだと思って対応する 14 checkMedId() 15 .then(() => { 16 response.status(200).end(); 17 }) 18 .catch(err => { 19 console.log(err.message); 20 response.status(500).send(err.message).end(); 21 })

投稿2018/03/08 06:55

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TarouKotani

2018/03/08 07:07

もろもろありがとうございます。。。 バージョンを確認し、最後の通りに直しましたがやはり同じエラーが出ます。。
miyabi-sun

2018/03/08 07:36

質問文を私のローカルで構文解析したところエラーは出ませんでした。 従って転記ミスの可能性が高いです。 またさらっとですがコードを一通り読みました。 ・getPreMedIdの中身が明らかにおかしいです。  DBに接続してpreMedIdよこせって言ってるのに、待たずに即返してるので絶対にUndefindが帰ります。 ・for文で90回もループしてますが、これ本当に合ってますか?  90回もループしつつその中で90回また固定値でループし始めるプログラムってかなりおかしいですよ。
guest

0

firebaseと言ってもたくさんのプロダクトがありますが、コードを拝見するにFirebase Cloud Functionsのこととお見受けします。

で、現時点(2018.05.15)におけるFirebase Cloud FunctionsのNode環境はv.6.11.5となります。

ローカルがv7.10以降でも、firebaseクラウド環境がNode v.6.11.5ですのでasync/awaitは一工夫しないと使えません。そのためasyncキーワードでunexpected tokenエラーが発生したものと思われます。


それと、少々耳の痛い話かもしれませんが、仮にasync/awaitが使えたとしてもコードの内容に突っ込みどころが多く想定している動作をしないように思います。

面倒かもしれませんが要素技術ごとに分解して簡略化した最小コードを書いてみることをお勧めします。

投稿2018/05/15 02:30

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問