2017-07-10 5 views
0

Mein Node-Skript importiert ein XHTML-Dokument und exportiert es mit dem Calibre-Dienstprogramm ebook-convert in E-Book-Formate. All das funktioniert gut.JavaScript: Wie wirkt sich die Außenwelt auf einen Rückruf aus?

Einige meiner Quelldokumente enthalten MathML-Markup zusätzlich zu anderen XHTML-Inhalten. Ich versuche MathJax-node zusammen mit mathjax-node-svg2png zu verwenden, um die MathML durch Bilder zu ersetzen.

Hier einige meiner stummen Code:

let einstein = ` 
<blockquote class='eqtn'> 
    <p>We will now prove the Pythogorian theorem: <mml:math> <mrow> <msup><mi> a </mi><mn>2</mn></msup> <mo> + </mo> <msup><mi> b </mi><mn>2</mn></msup> <mo> = </mo> <msup><mi> c </mi><mn>2</mn></msup> </mrow> </mml:math></p> 
</blockquote> 
<blockquote> 
    <p><mml:math><mrow><mi>e</mi><mo>=</mo><mi>m</mi><msup><mi>c</mi><mn>2</mn></msup></mrow></mml:math></p> 
</blockquote> 
    `; 

const re = /(\<mml:math.*?\<\/mml:math\>)/g; 

var equations = einstein.match(re); 

equations.forEach(equation => { 

    mjAPI.typeset({ 
    math: equation, 
    format: 'MathML', 
    png: true, 
    scale: 2 
    }, function(data) { 

    if(!data.errors) { 

     const imageTag = `<img alt="${data.speakText}" src="${data.png}" width="80%"/>`; 

     console.log(einstein.replace(equation, imageTag)); // This logs the string 
     // twice, each time with a different **single** equation replaced with 
     // an image tag. 

    } 

    }); 

}); 

Ich verstehe, warum dies die Ausgabe zweimal protokolliert, und ohne den Inhalt zu aktualisieren, aber ich bin nicht sicher, wie sie alle zusammen ziehen alle zu ersetzen die Gleichungen mit Bildern, vorausgesetzt, es ist asynchron. Gibt es Unterlagen, die mich in die richtige Richtung weisen könnten?

Antwort

3

Sie haben mehrere Möglichkeiten, dies zu erreichen. Du könntest sie entweder nacheinander tun, was du tun würdest, wenn eine Veränderung eine andere beeinflussen könnte.

Da Sie jedoch async erwähnt haben, vermute ich, dass sie nicht miteinander in Konflikt geraten, also können Sie sie parallel ausführen.

Sie können nur speichern Sie den Wert, bevor Sie console.log es:

einstein = einstein.replace(equation, imageTag)); 
console.log(einstein); 

einstein.replace() eine neue Zeichenfolge zurück, so dass Sie auf die Variable neu zuweisen in haben.

In diesem Fall würde ich jedoch eine Reihe von Ersetzungen erstellen und dann die Ersetzungen auf einmal anwenden, sobald Sie fertig sind. In diesem Fall müssen Sie auch wissen, wann Sie fertig sind. Dafür wäre es hilfreich, eine Art Zähler zu haben.

let einstein = ` 
<blockquote class='eqtn'> 
    <p>We will now prove the Pythogorian theorem: <mml:math> <mrow> <msup><mi> a </mi><mn>2</mn></msup> <mo> + </mo> <msup><mi> b </mi><mn>2</mn></msup> <mo> = </mo> <msup><mi> c </mi><mn>2</mn></msup> </mrow> </mml:math></p> 
</blockquote> 
<blockquote> 
    <p><mml:math><mrow><mi>e</mi><mo>=</mo><mi>m</mi><msup><mi>c</mi><mn>2</mn></msup></mrow></mml:math></p> 
</blockquote> 
    `; 

const re = /(\<mml:math.*?\<\/mml:math\>)/g; 

var equations = einstein.match(re); 

var equationsDone = 0; 
var replacements = {}; 
equations.forEach(equation => { 

    mjAPI.typeset({ 
    math: equation, 
    format: 'MathML', 
    png: true, 
    scale: 2 
    }, function(data) { 

    if(!data.errors) { 

     const imageTag = `<img alt="${data.speakText}" src="${data.png}" width="80%"/>`; 

     replacements[equation] = imageTag; 
     equationsDone++; 

     if (equationsDone === equations.length) { 
     applyReplacements(); 
     } 
    } 

    }); 

}); 

function applyReplacements() { 
    for (var equation in replacements) { 
    einstein = einstein.replace(equation, replacements[equation]); 
    } 

    console.log(einstein); 
} 

Was das bedeutet ist jedesmal, wenn der Rückruf aufgerufen wird, halten wir die Ersetzungen in einem Objekt, das wir später anwenden können. Wir erhöhen auch einen Zähler, den wir verwenden, um zu verfolgen, wie viele wir verarbeitet haben. Wenn wir equation.length verarbeitet haben, haben wir alle erledigt und können zum nächsten Schritt übergehen, der sie anwendet.

Um sie anzuwenden, die nur durch die Tasten des Objekts (die unsere Gleichungen sind) Schleife und die ersetzen. Von dort möchten Sie einstein abholen und etwas anderes damit machen.

Der Grund, warum ich es so machen würde ist, gibt mir mehr Kontrolle, wenn es Zeit ist, die Ersetzungen zu tun, und ich kann eine Aktion zu einer Zeit machen. Diese zusätzliche Kontrolle kann in Ihrem Anwendungsfall zu viel Aufwand sein, kann aber nützlich sein. Außerdem können Sie die ursprüngliche Zeichenfolge nicht ändern oder eine neue Zeichenfolge erstellen und stattdessen an einen Rückruf übergeben.

Verwandte Themen