NodeJS Приоритет ожидания - один ожидает выполнения другого в неправильном порядке (Express, SQLite3 db.all и db.run) - PullRequest
0 голосов
/ 07 декабря 2018

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

sales.js =

const sqlite3 = require('sqlite3').verbose()

const db = new sqlite3.Database('./database/stock.db', (err) => {
    if (err) return console.error(err.message)
    //console.log('Connected to the "stock.db" SQlite database.')
})

module.exports = {

total: function(cartlist) {
return new Promise((resolve) => {
    var total = 0
    for (x in cartlist){
        console.log(cartlist[x].price)
        total = total + cartlist[x].price
    }
    //console.log(total)
    resolve(total)
})},

stockloss: function(cartlist) {
return new Promise((resolve) => {
    var barcodes = []
    const len = (cartlist).length
    for(x in cartlist){
        var inp = JSON.stringify(cartlist[x].name)
        const sql = "SELECT barcode_id FROM products WHERE name ="+inp+";"
        db.all(sql, (err, data) => {
            if (err) console.error(err.message)
            barcodes = barcodes.concat(data)
            console.log(barcodes)
        })}
    resolve(barcodes)
})},

update: function(bars) {
return new Promise((resolve) => {
    for(x in bars){
        var bar = JSON.stringify(bars[x])
        console.log(bar)
        const sql = "UPDATE levels WHERE product_id ="+bar+" SET stock_level = stock_level - 1;"
        db.run(sql, function(err) {
            if (err) console.error(err.message)
            console.log("Record updated. ")
        })}
    resolve()
})}
}
}

index.js (части) =

'use strict'

const express = require('express')

const handlebars = require('express-handlebars').create({defaultLayout: 'main'})
const bodyParser = require('body-parser')
const app = express()
app.use(express.static('public'))
app.use(bodyParser.urlencoded({ extended: true }))
app.engine('handlebars', handlebars.engine)
app.set('view engine', 'handlebars')

const port = 8080

const sqlite3 = require('sqlite3').verbose()

const db = new sqlite3.Database('./database/stock.db', (err) => {
    if (err) return console.error(err.message)
    console.log('Connected to the "stock.db" SQlite database.')
})

const sales = require('./sale.js')

.,.

app.get('/checkout', async(req, res) => {
    total = await sales.total(cartlist)
    var bars = await sales.stockloss(cartlist)
    var prom = await sales.update(bars)
    cartlist = []
    res.render('checkout', {total})
    total = 0
})

.,.

Не уверен, что я делаю что-то не так с обещаниями, или я недостаточно разбираюсь в асинхронных функциях.Потенциально также существуют проблемы с db.run, так как я продолжаю видеть разные источники о том, как обновлять данные.

1 Ответ

0 голосов
/ 07 декабря 2018

Вот как я бы это сделал:

async function fetchFromDb(sql) {
    return new Promise(resolve, reject) {
            db.all(sql, (err, data) => {
            if (err) {
            console.error(err.message)
            reject(err)
            }
            resolve(data)
        })}
    }

async function updateRecord(sql) {
    return new Promise(resolve, reject) {
        db.run(sql, function(err) {
            if (err) {
                console.error(err.message)
                reject(err)
            }
            console.log("Record updated. ")
        resolve()
        }
    }
}


module.exports = {

    total: function(cartlist) {
        return new Promise((resolve) => {
            var total = 0
            for (x in cartlist) {
                console.log(cartlist[x].price)
                total = total + cartlist[x].price
            }
            //console.log(total)
            resolve(total)
        })
    },

    stockloss: async function(cartlist) {
        return new Promise((resolve) => {
            var barcodes = []
            const len = (cartlist).length
            for (x in cartlist) {
                var inp = JSON.stringify(cartlist[x].name)
                const sql = "SELECT barcode_id FROM products WHERE name =" + inp + ";"
                barcodes = barcodes.concat(await fetchFromDb(sql))
                resolve(barcodes)
            }
        })
    },

    update: async function(bars) {
        return new Promise((resolve) => {
            for (x in bars) {
                var bar = JSON.stringify(bars[x])
                console.log(bar)
                const sql = "UPDATE levels WHERE product_id =" + bar + " SET stock_level = stock_level - 1;"
                try {
                    await updateRecord(sql)
                } catch (err) {
                    reject(err)
                }
                resolve('successfully updated record')
            }
        })
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...