Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 尝试在循环中等待对象的元素_Javascript_Node.js_Asynchronous_Promise_Async Await - Fatal编程技术网

Javascript 尝试在循环中等待对象的元素

Javascript 尝试在循环中等待对象的元素,javascript,node.js,asynchronous,promise,async-await,Javascript,Node.js,Asynchronous,Promise,Async Await,我正在调用一个返回字段列表的API。其中一些字段具有相关字段,我需要查询API以获取这些字段 下面是我试图做的(主要是伪代码): 我遇到的问题是forEach没有等待,因此在put first console.log中,我得到了我期望的所有结果,除了具有集合的字段。因为我在等待这些,它永远不会进入返回的fieldObj。如果我不在那里等待,我会把它们放在fieldObj中,但当我打印出来时,它们只是承诺。 我一直尝试使用bluebird和异步npm库来获取foreach,在解析之前等待结果,但没

我正在调用一个返回字段列表的API。其中一些字段具有相关字段,我需要查询API以获取这些字段

下面是我试图做的(主要是伪代码):

我遇到的问题是forEach没有等待,因此在put first console.log中,我得到了我期望的所有结果,除了具有集合的字段。因为我在等待这些,它永远不会进入返回的fieldObj。如果我不在那里等待,我会把它们放在fieldObj中,但当我打印出来时,它们只是承诺。 我一直尝试使用bluebird和异步npm库来获取foreach,在解析之前等待结果,但没有成功。我能做些什么来度过这个难关

使用新代码编辑:

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();
    });
}

字段。forEach
不会等待承诺,因此您要在任何异步代码完成之前进行解析

用于。。。的

那么也不需要承诺构造函数

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;
}

字段。forEach
不会等待承诺,因此您要在任何异步代码完成之前进行解析

用于。。。的

那么也不需要承诺构造函数

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;
}

使用
for
,而不是
.forEach()
使循环等待
wait
.forEach()
不是设计为使用
wait
暂停的

也没有理由创造你自己的承诺。
async
函数已经返回一个承诺,因此您可以使用
wait
然后返回一个值,该值将自动成为返回的
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;
}

使用
for
,而不是
.forEach()
使循环等待
wait
.forEach()
不是设计为使用
wait
暂停的

也没有理由创造你自己的承诺。
async
函数已经返回一个承诺,因此您可以使用
wait
然后返回一个值,该值将自动成为返回的
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;
}

async/await不能像您认为的那样在
forEach
defaultforeach函数中不支持promise。另外,为什么要将'await'和
混合使用呢?然后在前两行代码中
let fields=await getFields();processFields(fields)。然后
-并不是说它错了,只是oddasync/await不像您在
forEach
默认forEach函数中所想的那样工作。另外,为什么要将'await'和
混合使用呢?然后在前两行代码中
let fields=await getFields();processFields(fields)。然后
-并不是说它错了,只是oddan答案,编辑为复制两个现有的正确答案,只有代码没有解释不是很有用答案,编辑为复制两个现有的正确答案,只有代码没有解释不是很有用我之所以选择这个答案是因为有很好的解释!我还有一点工作要做。getRelated函数在同一个字段上被调用了很多次,值被缓存在一个对象中,因为我还没有这个值,所以它会一直在同一个字段上调用它。所以我开始在对象中存储一个占位符,第一次为每个字段调用占位符时,每次调用都会返回该占位符,直到它被promise中的值替换,现在生活很好@FrancisLewis-如果“还没有值”导致了问题,那么听起来可能是您在
getRelated()
中没有正确使用承诺。如果做得好的话,这些承诺应该协调你的时间安排。也许您需要显示该代码,以便我们可以帮助您以正确的方式解决它。我刚刚用新代码编辑了我的帖子。我绝对不是100%肯定我在用最好的方法与getRelated联系。它目前正在工作,但是如果你有一些改进的想法,我将非常感激@弗朗西斯莱维斯-你所拥有的一切都很好。我个人会使用
请求承诺
库,而不是自己承诺。哇!那很容易!我完全支持不要在每次需要的时候都重新创建轮子。我选择这个答案是因为有很好的解释!我还有一点工作要做。getRelated函数在同一个字段上被调用了很多次,值被缓存在一个对象中,因为我还没有这个值,所以它会一直在同一个字段上调用它。所以我开始在对象中存储一个占位符,第一次为每个字段调用占位符时,每次调用都会返回该占位符,直到它被promise中的值替换,现在生活很好@FrancisLewis-如果“还没有值”导致了问题,那么听起来可能是您在
getRelated()
中没有正确使用承诺。如果做得好的话,这些承诺应该协调你的时间安排。也许您需要显示该代码,以便我们可以帮助您以正确的方式解决它。我刚刚用新代码编辑了我的帖子。我绝对不是100%肯定我在用最好的方法与getRelated联系。它目前正在工作,但是如果你有一些改进的想法,我将非常感激@弗朗西斯莱维斯-你所拥有的一切都很好。我个人会使用
请求承诺
库,而不是自己承诺。哇!那很容易!我完全支持不要在每次需要时都重新创建轮子。