Облачные функции Firebase: обещание не разрешается - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть некоторые проблемы с моим конкретным вызовом в облачной функции, которые, похоже, не решаются правильно.

Это код, который не нужно разрешать:

console.log('Getting Search Patterns');
let searchPatterns: FirebaseFirestore.QuerySnapshot;
  try {
    searchPatterns = await admin
      .firestore()
      .collection('FYP_LOCATIONS')
      .get();
    } catch (error) {
      console.error(error);
    }
 console.log(`Search Patterns Received: ${searchPatterns}`);

LOG: enter image description here

Как вы можете видеть в журнале, моя функция запускается до журнала консоли перед блоком try, затем останавливается до истечения времени ожидания функции.Я не уверен, что является причиной этой проблемы.

РЕДАКТИРОВАТЬ: я переформатировал свой код, разделив каждую из различных частей в моей облачной функции на отдельные функции, которые я могу вызвать;результирующая функция getSearchTerms () выглядит следующим образом:

async function getSearchTerms(): Promise<FirebaseFirestore.DocumentData[]> {
  try {
    const snapshot = await admin
      .firestore()
      .collection('FYP_LOCATIONS')
      .get();
    console.log('Get Returned');
    return snapshot.docs.map(doc => doc.data());
  } catch (e) {
    console.error(e);
    return [];
  }
}

Это все еще останавливается в той же точке выполнения функции, полная функция здесь, она обновлена ​​до последней версии:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as path from 'path';
import * as WordExtractor from 'word-extractor';
import * as textract from 'textract';
import suffixArray from './suffixArray';

// interface Location {
//   lid: string;
//   location_name: string;
//   location_type: string;
//   sentimental_value: number;
// }

// interface Context {
//   lid: string;
//   context_string: string;
//   fid: string;
// }

export const processFile = functions.storage.object().onFinalize(async file => {
  const serviceAccount = require(__dirname + '/../config/serviceAccount.json');

  admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://fyp-alex.firebaseio.com',
  });

  const firestore = admin.firestore();

  const fileBucket: string = file.bucket;
  const filePath: string = file.name;
  const fileDet: string = path.basename(filePath);
  const fileNameSplit: string[] = fileDet.split('.');
  const fileExt: string = fileNameSplit.pop();
  const fileName: string = fileNameSplit.join('.');
  const bucket = admin.storage().bucket(fileBucket);
  const fileRef = bucket.file(filePath);
  const _path: string = `/tmp/${fileName}.${fileExt}`;
  console.log(`File path ${filePath}`);
  console.log('Getting Download URL');
  try {
    console.log(`Downloading to: ${_path}`);
    await fileRef.download({ destination: _path });
    console.log('File Saved');
    console.log(`Getting Details: ${_path}`);
    const text: string = await getText(_path, fileExt);
    console.log(`Processing: ${fileName}`);
    console.log('Creating Suffix Array');
    const suffix_array = suffixArray(text);
    console.log(`Suffix Array Created: ${suffix_array}`);
    console.log('Getting Search Patterns');
    const searchTerms: FirebaseFirestore.DocumentData[] = await getSearchTerms();
    console.log('Search Patterns Received');
    const promises = [];
    const allContexts: Object[] = [];
    for (const searchDoc of searchTerms) {
      const searchTerm = searchDoc.location_name.toLowerCase();
      console.log(searchTerm);
      const matchedIndexes = search(text, searchTerm, suffix_array);
      const contexts = createContexts(matchedIndexes, searchDoc, text, fileName);
      allContexts.concat(contexts);
    }
    for (const context of allContexts) {
      const p = admin
        .firestore()
        .collection('FYP_CONTEXTS')
        .add(context);
      promises.push(p);
    }
    await Promise.all(promises);
    const data = {
      processed: 1,
    };
    return firestore.doc(`FYP_FILES/${fileName}`).update(data);
  } catch (e) {
    console.error(e);
    const data = {
      processed: 2,
    };
    return firestore.doc(`FYP_FILES/${fileName}`).update(data);
  }
});

async function getText(_path: string, fileExt: string) {
  let text: string = '';

  switch (fileExt) {
    case 'docx':
    case 'doc':
      const extractor = new WordExtractor();
      const extracted = await extractor.extract(_path);
      text = extracted.getBody();
      break;
    case 'pdf':
      break;
    case 'txt':
      textract.fromFileWithPath(_path, function(extractedError: any, string: string) {
        if (extractedError) {
          console.error(extractedError);
        }
        if (string !== null) {
          text = string;
        }
      });
      break;
    default:
      console.log('Unsupported File Type');
  }
  return text;
}

async function getSearchTerms(): Promise<FirebaseFirestore.DocumentData[]> {
  try {
    const snapshot = await admin
      .firestore()
      .collection('FYP_LOCATIONS')
      .get();
    console.log('Get Returned');
    return snapshot.docs.map(doc => doc.data());
  } catch (e) {
    console.error(e);
    return [];
  }
}

function createContexts(
  matchedIndexes: number[],
  searchDoc: FirebaseFirestore.DocumentData,
  text: string,
  fileName: string
) {
  console.log('Creating Contexts');
  const contexts = [];
  const searchTerm = searchDoc.location_name.toLowerCase();
  for (const index of matchedIndexes) {
    let left = index - 25;
    let right = index + searchTerm.length + 25;
    if (left < 0) {
      left = 0;
    }
    if (right > text.length) {
      right = text.length;
    }
    const context = text.substring(left, right);
    contexts.push({
      lid: searchDoc.lid,
      context_string: context,
      fid: fileName,
    });
  }
  return contexts;
}

function search(text: string, searchTerm: string, suffix_array: number[]) {
  console.log(`Beginning search for: ${searchTerm}`);
  let start = 0;
  let end = suffix_array.length;
  const matchedIndexes: Array<number> = [];

  while (start < end) {
    const mid: number = (end - 1) / 2;
    const index: number = suffix_array[mid];
    const finalIndex: number = index + searchTerm.length;
    if (finalIndex <= text.length) {
      const substring: string = text.substring(index, finalIndex);
      const match: number = searchTerm.localeCompare(substring);

      if (match === 0) {
        console.log(`Match Found at Index: ${index}`);
        matchedIndexes.push(index);
      } else if (match < 0) {
        end = mid;
      } else if (match > 0) {
        start = mid;
      }
      console.log(matchedIndexes);
    }
  }

  if (matchedIndexes.length === 0) {
    console.log(`No matches found for search term: ${searchTerm}`);
  }

  return matchedIndexes;
}

Надеюсь, полная функция обеспечит немного больше контекста.

Я несколько раз смотрел видео Дуга, но все еще сталкиваюсь с этим, я заметил, что удаление ожидание, которое, кажется,неудача (как при удалении обещания все вместе), казалось, привела к провалу более раннего ожидания.Это свидетельствует о том, что это проблема с обещаниями позже в функции, но я не могу всю жизнь найти проблему, я буду продолжать пытаться, но надеюсь, что это обеспечит некоторый полезный контекст.

1 Ответ

0 голосов
/ 28 февраля 2019

Вы не сообщаете функции о завершении асинхронных операций.Я предполагаю, что вы хотите собрать все асинхронные операции в массиве и подождать, пока все они завершатся, прежде чем позволить функции завершиться.хорошо и сделайте более тщательную работу по объяснению почему )

т.е..

const requests = [];
const things = [1,2,3];
for (let index = 0; index < things.length; index++) {
  const element = things[index];
  const promise = firebase.firestore().push(element);
  requests.push(promise);
}

return Promise.all(requests);
...