Импортированные асинхронные данные из другого модуля в Node не разрешаются, как я могу это исправить?

1

Это модуль, который собирает и экспортирует данные async: scraper.js

const express = require('express')
const cheerio = require('cheerio')
const request = require("tinyreq")
const fs = require('fs')
const _ = require('lodash')
const uuid = require('uuid/v4')
const async = require('async')


const mental_models = {
    url: 'https://www.farnamstreetblog.com/mental-models/',
    data: {}
}
const decision_making = {
    url: 'https://www.farnamstreetblog.com/smart-decisions/',
    data: {}
}
const cognitive_bias = {
    url: 'https://betterhumans.coach.me/cognitive-bias-cheat-sheet-55a472476b18',
    data: {}
}
const DATA_URLS = [mental_models, decision_making, cognitive_bias]

const filterScrape = async (source, params) => {

    let filtered_data = {
        topics: [],
        content: [],
        additional_content: []
    }

    let response = await scrape(source)

    try {
        let $ = cheerio.load(response)

        params.forEach((elem) => {
            let headers = ['h1', 'h2', 'h3']
            if ($(elem) && headers.includes(elem)) {

                let topic = {}
                let content = {}
                let id = uuid()
                topic.id = id
                topic.text = $(elem).text()

                if ($(elem).closest('p')) {
                    content.text = $(elem).closest('p').text()
                    content.id = id
                }
                filtered_data.topics.push(topic)
                filtered_data.content.push(content)
            } else if ($(elem) && !headers.includes(elem)) {

                let content = {}
                let id = uuid()
                content.text = $(elem).text()
                content.id = id
                filtered_data.additional_content.push(content)

            } else {

            }
        })

    }
    catch (err) {
        console.log(err)
    }

    return filtered_data

}

const scrape = (source) => {
    return new Promise((resolve, reject) => {
        request(source.url, function (err, body) {
            if (err) {
                reject(err)
                return
            }
            resolve(body)
        })
    })
}

const DATA = _.map(DATA_URLS, async (source) => {

    let params = ['h1', 'h2', 'h3', 'p']
    let new_data = await filterScrape(source, params)

    try {
        source.data = new_data
     }
     catch (err) {
         console.log(err)
     }

})
module.exports = DATA

Это модуль, который импортирует данные: neural.js

const brain = require('brain')
const neural_net = new brain.NeuralNetwork()
const DATA = require('./scraper')

console.log(DATA)

Очевидно, что не так много, я удалил код, так как переменная не разрешает. При регистрации он записывает обещание, но обещание не разрешается. Однако в импортированном модуле обещание регистрируется, а затем разрешается. Что дает? Должен ли я импортировать функцию, которая решает данные?

  • 0
    Разве async импорт не async с собственным async оператором?
  • 0
    Кроме того, я не думаю, что вы когда-либо использовали async библиотеку, но вместо этого вы хотите использовать async оператор ES6. И вы на самом деле делаете это, так почему const async = require('async') ?
Показать ещё 3 комментария
Теги:
async-await
asynchronous
import

1 ответ

0

Конечно, было бы лучше импортировать эту функцию, однако она не изменит проблему в вашем коде, который находится здесь:

const DATA = _.map(DATA_URLS, async (source) => {

Lodash не поддерживает асинхронную итерацию - так что вам нужно иметь какой-то другой метод, можно было бы использовать новейшую версию nodejs (10.x) и использовать асинхронную итерацию - но это не будет использовать полную мощность асинхронного кода,

Вы также можете использовать scramjet - инфраструктуру, которую поддерживает моя компания. Вышеприведенный код имеет следующий вид:

const {DataStream} = require("scramjet");
const DATA_URLS = [mental_models, decision_making, cognitive_bias];

module.exports = async () => DataStream.fromArray(DATA_URLS)
    .setOptions({maxParallel: 2})   // if you need to limit that at all.
    .map(async ({url}) => {
        let params = ['h1', 'h2', 'h3', 'p']
        let data = await filterScrape(source, params);

        return { url, data };
    })
    .toArray();

Другой файл будет иметь следующий вид:

const brain = require('brain')
const neural_net = new brain.NeuralNetwork()
const scraper = require('./scraper')

(async (){
    const DATA = await scraper();
    console.log(DATA);   // or do whatever else you were expecting...
})();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню