简体   繁体   中英

How do I return a number from a promise?

I am trying to return an number (expensePerProduct), which I will use to "PUT" the data in to an object, but this function returns a promise object and not just a number :( What do I do here?

This is my code:

const calculateExpense = async function (proName) {
        let expensePerProduct = 0;
        fetch('/purchase')
            .then(result => {
                if (result.status >= 400) {
                    throw new Error(result.status);
                } else {
                    return result.json();
                }
            })
            .then(result => {
                let totalExpense = 0;
                let totalQuantity = 0;
                for (let purchase of result) {
                    if (proName == purchase.productName) {
                        totalExpense += purchase.totalPrice;
                        totalQuantity += purchase.purchasedQuantity;
                    }
                }
                expensePerProduct = totalExpense / totalQuantity;
                return expensePerProduct;
            })
            .catch(err => console.log("Error: " + err));
    }

I am new to stackoverflow (and to JS), so tell me if you need more information..

As you're using async (but without the await ) I would separate out that code into a couple of functions, and use await to simplify the handling of the promises.

1) A new getData function.

2) A reduced calculateExpense function.

 async function getData(endpoint) { try { const res = await fetch(endpoint); if (res.status !== 200) throw new Error('Data error'); return await res.json(); } catch (e) { console.log(e); } } async function calculateExpense() { const data = await getData('/purchase'); let totalExpense = 0; let totalQuantity = 0; for (let purchase of data) { if (proName == purchase.productName) { totalExpense += purchase.totalPrice; totalQuantity += purchase.purchasedQuantity; } } return totalExpense / totalQuantity; } calculateExpense().then(result => console.log(result)); 

I've added a working copy (with a mocked fetch function) on jsFiddle .

From async_function documentation:

The async function declaration defines an asynchronous function, which returns an AsyncFunction object. An asynchronous function is a function which operates asynchronously via the event loop, using an implicit Promise to return its result.

This means you need to use await , only valid inside async functions, or then to get the value with which the promise was resolved.

Also note that you are not returning anything, so the promise is resolved with undefined "immediately" (not really true but easier to put it this way), because your function don't contain an await expression.

Try something like this:

// Using native promises:
const calculateExpense = function (proName) {
    return fetch('/purchase')
        .then((response) => {
            if (response.status >= 400) { throw new Error(response.status.toString()); }

            const result = response.json();

            let totalExpense = 0;
            let totalQuantity = 0;

            for (let purchase of result) {
                if (proName === purchase.productName) {
                    totalExpense += purchase.totalPrice;
                    totalQuantity += purchase.purchasedQuantity;
                }
            }

            return totalExpense / totalQuantity;
        });
};

// Using async/await:
const calculateExpense = async function (proName) {
    const response = await fetch('/purchase');

    if (response.status >= 400) { throw new Error(response.status.toString()); }

    const result = response.json();

    let totalExpense = 0;
    let totalQuantity = 0;

    for (let purchase of result) {
        if (proName === purchase.productName) {
            totalExpense += purchase.totalPrice;
            totalQuantity += purchase.purchasedQuantity;
        }
    }

    return totalExpense / totalQuantity;
};

calculateExpense('name')
    .then((expensePerProduct) => {
        // TODO: do something.
    })
    .catch(err => console.log(`Error: ${err}`));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM