简体   繁体   中英

Returning data from a Promise

I have a function which I use to populate some fields at load, which looks like this:

function billingAddress(){
    var urls = ['myURL'];
    var output = [];
    Promise.all(
        urls.map(
            u=>fetch(u).then(response => {
                if (!response.ok) {
                    throw new Error("Http Error " + response.status);
                }
                return response.json();
            })
        )
    ).then(texts => {
        fillAddress(texts);
        var info = getCustomerInfo(texts);
        console.log(info); //returns the data
        output.push(info);
    });
    return output;
}

The fillAddress function just fills in the respective fields on document load. In order to place an order, I need to gather the customer info and send a post request to the server. What I don't understand is how I can save the information from getCustomerInfo so I can process it at a later time.

For your reference,

function getCustomerInfo(data){
    var temp = data[0]['addresses']['shipping'];
    var info = {};
    info['address1'] = temp[0];
    info['address2'] = temp[1];
    info['city'] = temp[2];
    info['zip'] = temp[3];
    info['country'] = temp[4];
    info['state'] = temp[5];
    info['phone'] = temp[8];
    info['gst'] = temp[9];
    info['email'] = temp[10];
    info['items'] = [];
    return info;
}

Post function:

function placeOrder(){
    var info = billingAddress();
    console.log(info); //returns undefined
    $.ajax({
        url: 'placeOrder',
        contentType: 'application/json',
        type: 'POST',
        dataType: 'json',
        data: JSON.stringify(info),
        success: function(data){
            console.log(data);
        }
    });
}

placeOrder() is an onclick function, so I can't run it inside billingAddress()

You are getting your info data asynchronously, so you must access it asynchronously. What this means is that you can't return a value which is obtained from an asynchronous function call in a synchronous function, like you are trying to do with pushing info to output and then returning output . What is happening in your function is that output is being immediately returned as an empty array, while your asynchronous code executes in the background and then updates this array but only after it has already been returned. Instead, you should return a promise from your billingAddress function and access the data in the promise callback:

function billingAddress(){
    var urls = ['myURL'];
    return Promise.all(
        urls.map(
            u=>fetch(u).then(response => {
                if (!response.ok) {
                    throw new Error("Http Error " + response.status);
                }
                return response.json();
            })
        )
    ).then(texts => {
        fillAddress(texts);
        return getCustomerInfo(texts);
    });
}

function placeOrder(){
    billingAddress().then(info => {
        $.ajax({
            url: 'placeOrder',
            contentType: 'application/json',
            type: 'POST',
            dataType: 'json',
            data: JSON.stringify(info),
            success: function(data){
                console.log(data);
            }
        });
    });
}

Also, I would recommend using const or let instead of var and async/await to handle your promises, which will result in cleaner code:

async function billingAddress(){
    try {
        const urls = ['myURL'];
        const texts = await Promise.all(
            urls.map(u => {
                const response = await fetch(u);
                if (!response.ok) {
                    throw new Error("Http Error " + response.status);
                }
                return response.json();
            })
        );
        return getCustomerInfo(fillAddress(texts));
    } catch (e) {
        // handle errors
    }
}

async function placeOrder(){
    try {
        const info = await billingAddress();
        $.ajax({
            url: 'placeOrder',
            contentType: 'application/json',
            type: 'POST',
            dataType: 'json',
            data: JSON.stringify(info),
            success: function(data){
                console.log(data);
            }
        });
    } catch (e) {
        // handle errors
    }
}

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