簡體   English   中英

在等待異步 function 后運行同步調用

[英]Running a synchronous call after awaiting an asynchronous function

我正在編寫一個節點 js 程序,如下所示。 此代碼的目的是從 API 的多個頁面中解析(可變數量的頁面,因此抓取第一頁以查看要抓取多少頁),然后將所有頁面上傳到 MongoDB,然后使用“分析頁面”另一個文件中的 function (操作關鍵字):

const MongoClient = require('mongodb').MongoClient
const fetch = require('node-fetch')
const config = require('./config.json')
const manipulate = require('./manipulateDB')

async function startAHLoop() {
        async function getAuctionPage(page = 0) {
            return fetch(`https://website.net/page/${page}`).then(res => {
                return res.json()
            }).catch (error => console.error("Faced an error: " + error))
        }

    async function getFullAH() {
        try {
            let ah = []
            let completedPages = 0
            let firstPage = await getAuctionPage(0)
            for (let i = 1; i <= firstPage.totalPages; i++) {
                getAuctionPage(i).then((page) => {
                    if (completedPages !== firstPage.totalPages - 1) {
                        completedPages++
                    }
                    if (page.success) {
                        for (auction of page.auctions) {
                            ah.push(auction)
                            if (completedPages == firstPage.totalPages - 1) {
                                completedPages++
                            }
                        }
                    } else if (completedPages == firstPage.totalPages - 1) {
                        completedPages++
                    }
                })
            }
            // Wait for the whole ah to download
            while (completedPages !== firstPage.totalPages)
                await new Promise((resolve) => setTimeout(resolve, 10))
            return ah
        } catch (e) {
            console.log('Failed to update auctions', e)
            return
        }
    }

    async function main() {
        let startTime = Date.now()
        if (!db.isConnected()) await connectToDB()
        let auctionCollection = data.collection('auctions')

        let ah = await getFullAH()
        let timeTaken = Date.now() - startTime
        if (typeof ah.ok == 'undefined') {
            auctionCollection.drop()
            auctionCollection.insertMany(ah)
            console.log(`Auction update complete in ${timeTaken} ms ${Date().toLocaleString()}`)
            console.log("Starting analysis")
            await auctionCollection.insertMany(ah)
            manipulate.printAHInfos()
        } else {
            console.log(`Auction update failed in ${timeTaken} ms ${Date().toLocaleString()}`)
        }
        // This essentially is the delay instead of every 60000 ms
        setTimeout(main, 60000 - timeTaken)
    }

    main() 
}

async function connectToDB(isFirstConnect) {
    console.log('Connecting to db...')
    MongoClient.connect(
        config.mongoSRV,
        { useNewUrlParser: true, useUnifiedTopology: true },
        (err, DB) => {
            if (err) return connectToDB()
            db = DB
            skyblock = DB.db('skyblock')
        }
    )

    while (typeof db == 'undefined') {
        await new Promise((resolve) => setTimeout(resolve, 10))
    }

    if (!db.isConnected()) {
        console.log('Something weird happened... re-starting db connection')
        return connectToDB()
    }
    console.log('Successful connection to database')
    if (isFirstConnect) startAHLoop()
    return db
}
connectToDB(true)
      

我正在尋找一種方法等到collection.insertMany(ah)完成后再進行manipulate.AHdata

我得到的問題是在collection.insertMany(ah)完成之前調用了manipulate.AHdata 操作時的結果如下。AHdata 輸出“調用”:

Invoked
Connecting to db...

我嘗試使用以下內容:

collection.insertMany(ah)
await collection.insertMany(ah)
manipulate.AHdata

但它不起作用......知道我能做什么嗎?

感謝您的幫助,祝您有美好的一天!

跟進我的所有評論和觀點,這是我認為更好(但顯然未經測試)的代碼版本:

const MongoClient = require('mongodb').MongoClient
const fetch = require('node-fetch')
const config = require('./config.json')
const manipulate = require('./manipulateDB')

let auctionCollection

async function getAuctionPage(page = 0) {
    try {
        const response = await fetch(`https://website.net/page/${page}`)
        const data = await response.json()
        return data
    } catch (err) {
        console.error("Faced an error: " + err)
    }
}

async function getFullAH() {
    try {

        let ah = []
        let firstPage = await getAuctionPage(0)

        for (let i = 1; i <= firstPage.totalPages; i++) {

            const page = await getAuctionPage(i);

            for (let auction of page.auctions) ah.push(auction);
        }

        return ah
    } catch (e) {
        console.log('Failed to update auctions', e)
        return
    }
}

async function main() {

    let startTime = Date.now()
    let ah = await getFullAH()
    let timeTaken = Date.now() - startTime

    auctionCollection.drop()
    auctionCollection.insertMany(ah)
    console.log(`Auction update complete in ${timeTaken} ms ${Date().toLocaleString()}`)
    console.log("Starting analysis")
    await auctionCollection.insertMany(ah)
    manipulate.printAHInfos()

    // This essentially is the delay instead of every 60000 ms
    setTimeout(main, 60000 - timeTaken)
}

async function connectToDB() {

    console.log('Connecting to db...')

    let db

    try {
        db = await MongoClient.connect(
            config.mongoSRV,
            { useNewUrlParser: true, useUnifiedTopology: true });
    } catch (err) {
        return connectToDB()
    }

    auctionCollection = db.collection('auctions');
    console.log('Successful connection to database')
    main() // You don't need hacks and verifications to check if the DB is connected. If there was a problem, it got caught in the catch()
}
connectToDB()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM