javascript - 异步函数不按进程顺序工作

标签 javascript asynchronous promise

我正在 NodeJS 中使用异步 javascript。我有一个函数,可以修改它的参数,然后解析发送到 SocketIO 客户端。问题是,该函数没有按顺序处理行,它先进行一些处理,然后再进行一些处理,我认为这只是关于异步 JavaScript 问题,但我不明白如何解决这个问题。

我的功能,

const processStylesAndImages = (target, targetSlug, id, socket, styles, images, protocol, CSS, DOM) => {
    return new Promise(async (resolve, reject) => {
        let { coverage } = await CSS.takeCoverageDelta();
        let { nodes } = await DOM.getFlattenedDocument({ depth: -1 });
        styles = styles.filter(style => !style.isInline && style.sourceURL.trim().length > 0);
        for(let style of styles) {
            style.mediaQueries = [];
            let m;
            while(m = mediaQueryRegex.exec(style.css)) {
                style.mediaQueries.push({
                    startOffset: m.index,
                    endOffset: m.index + m[0].length,
                    rule: style.css.slice(m.index, m.index + m[0].length),
                    used: true,
                    rules: []
                });
            }
            style.used = [];
            while(m = charsetRegex.exec(style.css)) {
                style.used.push({
                    startOffset: m.index,
                    endOffset: m.index + m[0].length,
                    used: true,
                    styleSheetId: style.styleSheetId
                });
            }
            while(m = importRegexVariable.exec(style.css)) {
                style.used.push({
                    startOffset: m.index,
                    endOffset: m.index + m[0].length,
                    used: true,
                    styleSheetId: style.styleSheetId
                });
            }
            let fontFaces = [];
            while(m = fontFaceRegex.exec(style.css)) {
                fontFaces.push(m);
            }
            fontFaces.forEach((m, index) => {
                let pushed = false;
                let props = css.parse(style.css.slice(m.index, m.index + m[0].length)).stylesheet.rules[0].declarations;
                let fontFamily;
                let fontWeight = null;
                props.forEach(prop => {
                    if(prop.property == 'font-family') {
                        if(prop.value.startsWith("'") || prop.value.startsWith('"')) {
                            prop.value = prop.value.slice(1);
                        }
                        if(prop.value.endsWith("'") || prop.value.endsWith('"')) {
                            prop.value = prop.value.slice(0, -1);
                        }
                        prop.value = prop.value.toLowerCase();
                        fontFamily = prop.value;
                    } else if(prop.property == 'font-weight') {
                        fontWeight = prop.value;
                    }
                });
                if(fontWeight == null || 'normal') fontWeight = 400;
                if(style.sourceURL == 'https://www.webmedya.com.tr/css/font-awesome.min.css') console.log(fontFamily, fontWeight);
                nodes.forEach(async (node, nodeIndex) => {
                    let { computedStyle } = await CSS.getComputedStyleForNode({ nodeId: node.nodeId });
                    computedStyle = computedStyle.filter(item => {
                        return (item.name == 'font-family' || item.name == 'font-weight') && (item.value !== '' || typeof(item.value) !== 'undefined');
                    });
                    let elementFontFamily;
                    let elementFontWeight;
                    computedStyle.forEach(compute => {
                        if(compute.name == 'font-family' && compute.value !== '' && typeof(compute.value) !== 'undefined') {
                            elementFontFamily = compute.value.toLowerCase();
                        } else if(compute.name == 'font-weight') {
                            if(compute.value !== '' && typeof(compute.value) !== 'undefined') {
                                if(compute.value == 'normal') {
                                    elementFontWeight = 400;
                                } else {
                                    elementFontWeight = compute.value;
                                }
                            } else {
                                elementFontWeight = 400;
                            }
                        }
                    });
                    if(elementFontFamily && elementFontWeight) {
                        if(elementFontFamily.includes(fontFamily) && (elementFontWeight == fontWeight)) {
                            if(!pushed) {
                                //console.log(m);
                                style.used.push({
                                    startOffset: m.index,
                                    endOffset: m.index + m[0].length,
                                    used: true,
                                    styleSheetId: style.styleSheetId
                                });
                                pushed = true;
                                console.log('Pushed', style.css.slice(m.index, m.index + m[0].length));
                            }
                        }
                    }
                });
            });
            console.log('BBBBBBBBBBBBB');
            console.log('AAAAAAAAAAAA');
            let parsedSourceURL = url.parse(style.sourceURL.trim());
            if(parsedSourceURL.protocol === null && parsedSourceURL.host === null) {
                if(style.sourceURL.trim().startsWith('/')) {
                    style.sourceURL = `${target}${style.sourceURL.trim()}`;
                } else {
                    style.sourceURL = `${target}/${style.sourceURL.trim()}`;
                }
            };
            style.parentCSS = "-1";
            style.childCSSs = [];
            style.childCSSs = getImports(style.css, style.sourceURL.trim(), target);
            coverage.forEach(item => {
                if(item.styleSheetId.trim() == style.styleSheetId.trim())
                    style.used.push(item);
            });
            style.mediaQueries.forEach((mediaQuery, index) => {
                style.used.forEach((usedRule, usedIndex) => {
                    if(usedRule.startOffset > mediaQuery.startOffset && usedRule.endOffset < mediaQuery.endOffset) {
                        style.mediaQueries[index].rules.push(style.used[usedIndex]);
                        style.used[usedIndex] = false;
                    }
                });
            });
            style.used = style.used.filter(item => {
                return item !== false;
            });
            style.mediaQueries = style.mediaQueries.filter(item => {
                return item.rules.length > 0;
            });
            style.mediaQueries.forEach((mediaQuery, index) => {
                mediaQuery.rules.sort((a, b) => a.startOffset - b.startOffset);
            });
            style.used = style.used.concat(style.mediaQueries);
            delete style.mediaQueries;
            style.used.sort((a, b) => a.startOffset - b.startOffset);
            let compressedCss = "";
            if(style.used.length > 0) {
                style.used.forEach(usedRule => {
                    if(usedRule.rule && usedRule.rules.length > 0) {
                        let queryRule = usedRule.rule.match(/@media[^{]+/)[0];
                        compressedCss += queryRule + '{';
                        usedRule.rules.forEach(item => {
                            compressedCss += style.css.slice(item.startOffset, item.endOffset);
                        });
                        compressedCss += '}';
                    } else {
                        compressedCss += style.css.slice(usedRule.startOffset, usedRule.endOffset);
                    }
                });
            };
            style.compressedCss = compressedCss;
        }
        console.log('CCCCCCCCCCCCCCCCCCCC');
        styles = preTraverse(styles, targetSlug, id);
        debug('CSS Dosyaları İşlendi!');
        fs.readFile(`./data/${targetSlug}/${id}/cimg/statistics.json`, async (err, data) => {
            if(err) reject(err);
            try {
                data = JSON.parse(data);
                await CSS.stopRuleUsageTracking();
                await protocol.close();
                if(typeof(styles) !== 'undefined' && styles.length > 0) {
                    debug('IMG Dosyaları İşlendi!');
                    socket.emit('log', { stage: 6, images, data, styles });
                    resolve({ images, data, styles });
                } else {
                    debug('IMG Dosyaları İşlendi!');
                    socket.emit('log', { stage: 6, images, data, styles: [] });
                    resolve({ images, data, styles: [] });
                };
            } catch(e) {
                reject(e);
            };
        });
    });
};

函数针对某些参数启动时的结果,

BBBBBBBBBBBBB
AAAAAAAAAAAA
fontawesome 400
BBBBBBBBBBBBB
AAAAAAAAAAAA
BBBBBBBBBBBBB
AAAAAAAAAAAA
CCCCCCCCCCCCCCCCCCCC
Pushed @font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}
Pushed @font-face{font-family:open sans;font-style:normal;font-weight:300;src:local('Open Sans Light'),local('OpenSans-Light'),url(https://fonts.gstatic.com/s/opensans/v15/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2) format('woff2');unicode-range:U+0460-052F,U+20B4,U+2DE0-2DFF,U+A640-A69F}
Pushed @font-face{font-family:open sans;font-style:normal;font-weight:300;src:local('Open Sans Light'),local('OpenSans-Light'),url(https://fonts.gstatic.com/s/opensans/v15/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}

预期结果是,

BBBBBBBBBBBBB
AAAAAAAAAAAA
fontawesome 400
Pushed @font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}
BBBBBBBBBBBBB
AAAAAAAAAAAA
Pushed @font-face{font-family:open sans;font-style:normal;font-weight:300;src:local('Open Sans Light'),local('OpenSans-Light'),url(https://fonts.gstatic.com/s/opensans/v15/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2) format('woff2');unicode-range:U+0460-052F,U+20B4,U+2DE0-2DFF,U+A640-A69F}
Pushed @font-face{font-family:open sans;font-style:normal;font-weight:300;src:local('Open Sans Light'),local('OpenSans-Light'),url(https://fonts.gstatic.com/s/opensans/v15/DXI1ORHCpsQm3Vp6mXoaTZX5f-9o1vgP2EXwfjgl7AY.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
BBBBBBBBBBBBB
AAAAAAAAAAAA
CCCCCCCCCCCCCCCCCCCC

该函数跳过 JSFiddle 第 6 行的 for 循环。它的行为类似于异步过程,但我希望它的行为类似于同步

谢谢!

最佳答案

您应该在 fiddle 中的第 39 行等待 new Promise((res, rej) => { promise 。您使用 .then 创建一个 promise ().catch() 处理程序,您可以在循环中运行它,但不要 await 它。这意味着,promise 被触发,但代码已经继续到下一个迭代。

因此,尝试在 39 行的 new Promise(...) 前面添加 await 并运行它。

关于javascript - 异步函数不按进程顺序工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53986886/

相关文章:

javascript - 在 JS 中使用默认的谷歌地图标记

ios - 未调用 selectRowAtIndexPath

javascript - 如何从 MongoDB 中的数组中提取对象

javascript - nodejs v8.11.2 .foreach 不是函数错误

c# - 异步 Json.net 反序列化

node.js - 包装 process.nextTick 导致超出最大调用堆栈大小

javascript - 如何创建一个返回等待 EventEmitter 的 Promise 的函数?

node.js - TypeError : invNum. next 不是一个函数

javascript - 在示例中将 promise 与 Node.js 函数结合使用

javascript - 用子元素的值替换元素文本