Неверный вывод, нужен синхронный цикл - PullRequest
0 голосов
/ 05 июня 2018
exports.calculateGstBaseOnInput = function(req, res) {
    console.log("welcome");
    for (var item of req.body.so_items) {
        req.productid = item.productid;
        req.qty = item.qty;
        getItemDetail(req, res).then(function(result) {
            return getCartItems(req, res);
        }).then(function(result) {
            return calculateGST(req, res);
        })
    }
}

getItemDetail = function(req, res) {
    return new Promise(function(resolve, reject) {
        console.log("inside getItemDetail");

        var SQL = "mysql query";
        mysqlConnect.query(SQL, function(err, result, fields) {
            if (err) {
                console.log("inside err");

                res.json({ status: 'Failure', statusMessage: 'item does not exist' });
            } else if (result.length < 0) {
                console.log("inside length 0");

                res.json({ status: 'Failure', statusMessage: 'item does not exist' });
            } else {
                req.itemdetail = result;
                console.log("price inside getitemdetail= ", req.itemdetail[0].price);

                //callback();
            }
        });
        resolve('done');
    });
}

getCartItems = function(req, res) {
    return new Promise(function(resolve, reject) {
        console.log("inside getCartItems");
        var SQL = "mysql query";
        mysqlConnect.query(SQL, function(err, result, fields) {
            if (err) {
                res.json({ status: 'Failure', statusMessage: 'item does not exist' });
            } else if (result.length < 0) {
                res.json({ status: 'Failure', statusMessage: 'item does not exist' });
            } else {
                req.cartItems = result;
                //callback();
            }
        });
        resolve('done');
    });
}

calculateGST = function(req, res) {
    return new Promise(function(resolve, reject) {
        console.log("inside calculateGST");

        if (req.userDetails[0].is_gst_included) {
            //total = req.qty * req.itemdetail[0].price;
            // console.log("price = ",req.itemdetail[0].price);
            //callback();
        } else {
            //total = req.qty * req.itemdetail[0].price;
            //console.log("price = ",req.itemdetail[0].price);
            //total = req.qty * req.itemdetail[0].price;

        }

        resolve('done');
    });
}

Фактический вывод:

inside getItemDetail
inside getItemDetail
inside getCartItems
inside getCartItems
inside calculateGST
inside calculateGST

Ожидаемый вывод (требуемый вывод):

inside getItemDetail
 inside getCartItems
    inside calculateGST
    inside getItemDetail
    inside getCartItems
    inside calculateGST

как мне добиться этого без установки какого-либо времени.

1 Ответ

0 голосов
/ 05 июня 2018

Вы немедленно resolve вместо разрешения в обратном вызове, предоставленном mysqlConnect.query().

Рассмотрите сокращенную версию вашей getItemDetail функции:

function getItemDetail(req, res) {
    return new Promise(function(resolve, reject) {
        var SQL = "mysql query";
        mysqlConnect.query(SQL, function(err, result, fields) {
            // Stuff
        });
        resolve('done');
    });
}

Это логикаis:

  1. Создать новое обещание
  2. Начать query
  3. resolve()
  4. Как называется getItemDetail делает то, что долженпотому что getItemDetail разрешено
  5. query заканчивается через некоторое время

Вместо этого вы, вероятно, должны делать что-то вроде этого, где resolve находится в пределах queryобратный вызов:

function getItemDetail(req, res) {
    return new Promise(function(resolve, reject) {
        var SQL = "mysql query";
        mysqlConnect.query(SQL, function(err, result, fields) {
            // Stuff
            resolve('done');
        });
    });
}

Логика здесь:

  1. Создать новое обещание
  2. Начать query
  3. getItemDetail вызывающийне должен ничего делать, потому что getItemDetail еще не решено
  4. query завершается в какой-то момент, и вызывается обратный вызов, который вызывает resolve
  5. getItemDetail, вызывающий абонент теперьпродолжить, так как было сказано, что функция разрешена

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


Вы также должны рассмотреть возможность использования async/await.Рассмотрим этот сокращенный пример, используя ваш код в качестве основы:

const mysqlConnect = {
    query(sql, cb) {
        setTimeout(() => {
            cb(null, ["foo"], ["bar"]);
        });
    }
};

(async function() {
    const t = await calculateGstBaseOnInput({
        body: {
            so_items: ["a", "b", "c"]
        }
    });
}());

async function calculateGstBaseOnInput(req, res) {
    for (var item of req.body.so_items) {
        const itemDetail = await getItemDetail(req, res);
        const cartItems = await getCartItems(req, res);
        const gst = await calculateGST(req, res);
    }
}

function getItemDetail(req, res) {
    console.log("getItemDetail");
    return new Promise(function(resolve, reject) {
        var SQL = "mysql query";
        mysqlConnect.query(SQL, function(err, result, fields) {
            // Stuff
            resolve('done');
        });
    });
}

function getCartItems(req, res) {
    return new Promise(function(resolve, reject) {
        console.log("---getCartItems");
        var SQL = "mysql query";
        mysqlConnect.query(SQL, function(err, result, fields) {
            // Stuff
            resolve('done');
        });
    });
}

function calculateGST(req, res) {
    return new Promise(function(resolve, reject) {
        console.log("------calculateGST");
        // Stuff
        resolve('done');
    });
}

Это выводит:

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