मैं एक एपीआई को कॉल कर रहा हूं जो फ़ील्ड की एक सूची देता है। उनमें से कुछ क्षेत्रों में संबंधित क्षेत्र हैं, जिन्हें मुझे उन क्षेत्रों को प्राप्त करने के लिए एपीआई से पूछताछ करने की आवश्यकता है।

तो यहाँ मैं क्या करने का प्रयास कर रहा हूँ (ज्यादातर छद्म कोड):

// gets initial set of fields. This part works.
let fields = await getFields();
processFields(fields).then(data => {
    console.log('data now contains object with all fields and related fields', data);
});

async function processFields(fields) {
    let fieldObj = {};

    return new Promise(resolve => {
        fields.forEach(async field => {
            if (field.collection) {
                let related = await getRelated(field.relatedListFieldType);
                fieldObj[field.id] = {
                    name: field.name,
                    display: field.display,
                    fields: related
                };
            } else {
                fieldObj[field.id] = {name: field.name, display: field.display};
            }
        });

        resolve(fieldObj);
    });
}

async function getRelated(name) {
    … some code here and return promise …
}

जिस मुद्दे में मैं चल रहा हूं वह है क्योंकि प्रत्येक प्रतीक्षा नहीं करता है, इसलिए पहले कंसोल.लॉग में, मुझे उन सभी परिणामों को वापस मिल जाता है जिनकी मैं उम्मीद कर रहा हूं, उन क्षेत्रों को छोड़कर जिनके पास संग्रह है। चूंकि मैं उनका इंतजार कर रहा हूं, यह कभी भी लौटे हुए क्षेत्र ओबीजे में प्रवेश नहीं करता है। अगर मैं वहां इंतजार नहीं करता हूं, तो मैं उन्हें ओब्ज के क्षेत्र में ले जाता हूं, लेकिन जब मैं उन्हें प्रिंट करता हूं, तो वे सिर्फ वादे होते हैं। मैं एक फ़ोरैच प्राप्त करने का प्रयास करने के लिए ब्लूबर्ड और एसिंक एनपीएम लाइब्रेरी का उपयोग करने में असफल प्रयास कर रहा हूं जो हल करने से पहले परिणामों की प्रतीक्षा करेगा, लेकिन मैं सफल नहीं हुआ हूं। मैं इससे उबरने के लिए क्या कर सकता हूं?

नए कोड के साथ संपादित करें:

async function processFields(data) {

    let fieldObj = {};

    for (let field of data.data) {
        if (field.isCollection) {
            let related = await getRelated(field.relatedListFieldType);
            fieldObj[field.id] = {
                name: field.name,
                display: field.display,
                fields: related
            };
        } else {
            fieldObj[field.id] = {
                name: field.name,
                display: field.display
            }
        }
    }

    return fieldObj;
}

async function getRelated(name) {
    let relatedData = '';

    name = name.toLowerCase();
    if (objects[name]) {
        return objects[name];
    } else {
        // put a placeholder here so we only request this once
        objects[name] = {};
    }

    return new Promise(resolve => {
        let relatedOptions = Object.assign(options, {
            path: encodeURI(`/api/objects/v1/${name}/_describe`)
        });

        let req = https.request(relatedOptions, res => {
            res.on('data', chunk => {
                relatedData += chunk;
            });

            res.on('error', err => {
                console.log('had error', err);
            });

            res.on('end', async () => {
                objects[name] = await processFields(JSON.parse(relatedData));
                resolve(objects[name]);
            });
        });

        req.end();
    });
}
0
Francis Lewis 9 अक्टूबर 2018, 03:50

3 जवाब

सबसे बढ़िया उत्तर

लूप को await के साथ प्रतीक्षा करने के लिए for का उपयोग करें, .forEach() का नहीं। .forEach() को await के साथ रुकने के लिए नहीं बनाया गया है।

अपना खुद का वादा बनाने का भी कोई कारण नहीं है। async फ़ंक्शन पहले से ही एक वादा देता है ताकि आप केवल await का उपयोग कर सकें और फिर एक मान वापस कर सकें जो स्वचालित रूप से लौटाए गए async वादे का हल मूल्य बन जाएगा।

उदाहरण के लिए, आप इसे इस तरह कर सकते हैं:

async function processFields(fields) {
    let fieldObj = {};

    for (let field of fields) {
        if (field.collection) {
            let related = await getRelated(field.relatedListFieldType);
            fieldObj[field.id] = {
                name: field.name,
                display: field.display,
                fields: related
            };
        } else {
            fieldObj[field.id] = {name: field.name, display: field.display};
        }
    }
    return fieldObj;
}
1
jfriend00 9 अक्टूबर 2018, 00:59

fields.forEach वादों की प्रतीक्षा नहीं करता है, इसलिए आप किसी भी async कोड के पूरा होने से पहले समाधान कर रहे हैं

के लिए उपयोग करें ... का

फिर प्रॉमिस कंस्ट्रक्टर की भी जरूरत नहीं है

async function processFields(fields) {
    let fieldObj = {};

    for (let field of fields) {
        if (field.collection) {
            let related = await getRelated(field.relatedListFieldType);
            fieldObj[field.id] = {
                name: field.name,
                display: field.display,
                fields: related
            };
        } else {
            fieldObj[field.id] = {name: field.name, display: field.display};
        }
    }
    return fieldObj;
}
1
Jaromanda X 9 अक्टूबर 2018, 00:57
async function processFields(fields) {
    let fieldObj = {};

    for(var field of fields) {
        if (field.collection) {
                let related = await getRelated(field.relatedListFieldType);
                fieldObj[field.id] = {
                    name: field.name,
                    display: field.display,
                    fields: related
                };
            } else {
                fieldObj[field.id] = {name: field.name, display: field.display};
            }
    }
    return fieldObj;
}
0
gu mingfeng 9 अक्टूबर 2018, 00:59