为什么即使在等待所有承诺解决之后,最终的 console.log 也没有显示整个数据?

编辑

因此,如果我setTimeout在 final 上设置 a console.log,它会很好地记录下来,但我想我的新问题是,即使有then陈述,为什么在一切都解决之后它不会触发?

我有一个奇怪的错误,我无法弄清楚为什么它没有打印我期望的整个结构。我没有收到任何错误,我确实尝试输入了一些console.log,但似乎只是让anyOf属性记录下来。它总是显示为空。

我的主要问题是hold没有正确记录。它显示anyOf为空。

const $ = require('cheerio');

const Axios = require('axios').default;

let name = 'sqs';

let basePath = '/AWS_SQS.html'



let hold = {

    '$schema': 'http://json-schema.org/draft-07/schema#',

    '$id': `cf${name}`,

    'description': `CF ${name}`,

    'properties': {

        'Type': {

            'type': 'string',

            'enum': [],

        },

    },

    'anyOf': [] // this keeps coming up empty

};


let typeProperties = (t, p) => {

    return {

        'if': { 'properties': { 'Type': { 'const': t } } },

        'then': {

            'properties': {

                'Properties': {

                    'type': 'object',

                    'properties': p,

                },

            },

        },

    }

}


const makeRequest = (bpath) => {

    let url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/' + bpath

    return Axios.get(url)

        .then((res) => {

            return res.data;

        })

        .catch(console.log);

};


let getData = makeRequest(basePath).then((data) => {

    let match = $('.listitem>p>a', data);

    match.map((i, e) => {

        let t = $(e);

        hold.properties.Type.enum.push(t.text());

        makeRequest(t.attr('href')).then((newdata) => {

            let holdProperties = {}

            let pType = $($('.variablelist', newdata)[0])

            $('.term>.code', pType).map((i, elem) => {

                let propertyName = $(elem).text()

                holdProperties[propertyName] = {}

            })

            hold.anyOf.push(typeProperties(t.text(), holdProperties))

        }).catch(console.log)

    });

}).catch(console.log)


getData.then(() => {

    // Why doesnt this log fully once everything is resolved? If i put a setTimeout here, it will work fine

    console.log(JSON.stringify(hold));

}).catch(console.log)


温温酱
浏览 145回答 1
1回答

收到一只叮咚

在与 关联的代码中getData(),您正在执行makeRequest().then()a .map(),但完全忽略了返回的承诺makeRequest()。你不是在等他们。您需要使用Promise.all()来等待所有这些,这样您就可以返回一个与所有其他完成的承诺相关联的承诺。你可以这样做:let getData = makeRequest(basePath).then((data) => {    let match = $('.listitem>p>a', data).get();    return Promise.all(match.map(item => {        let t = $(item);        hold.properties.Type.enum.push(t.text());        return makeRequest(t.attr('href')).then((newdata) => {            let holdProperties = {}            let pType = $($('.variablelist', newdata)[0])            $('.term>.code', pType).map((i, elem) => {                let propertyName = $(elem).text()                holdProperties[propertyName] = {}            })            hold.anyOf.push(typeProperties(t.text(), holdProperties))        }).catch(err => {            console.log(err);            throw err;              // propagate error back to caller        });    }));}).catch(console.log)getData.then(() => {    // Why doesnt this log fully once everything is resolved? If i put a setTimeout here, it will work fine    console.log(JSON.stringify(hold));}).catch(console.log)这段代码的变化:在.map()addreturn这样你就有了return makeRequest(...),所以你.map()会返回一个 promises 数组。有了这些来自.map()use的承诺,return Promise.all(match.map(...))所以你正在等待来自的所有承诺.map(),所以你正在返回那个摘要承诺。使用从 jQuery/cheerio 获取真正的数组,.get()以便您可以使用真正的 ES6 迭代操作。然后将参数切换.map()为匹配array.map()使用的内容。请注意,您的hold.anyOf数组的结果将无法保证顺序,因为您的所有并行makeRequest()调用都可以按任何顺序完成。如果您希望它们按顺序排列,您应该从.then()处理程序返回值,然后按顺序累积所有值,然后您可以从数组中使用它们,该数组是它们按照您请求它们的顺序Promise.all()的解析值。Promise.all()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript