简体   繁体   中英

Await not awaiting

I am getting started with both MathJax and using await where I am formatting a series of lines which can contain math. The math is denoted by the delimiters $...$ .

Problem: I need to wait for MathJax to complete its conversion (I do get some sort of html output) however the conversion is not waiting and the rest of format() is executing. Part of my code is modeled after the answer given in this question .

  function MJ(math) {
    // as per the documentation, this returns a promise if no callback is set
    return mathjax.typeset({
      math: math,
      format: "inline-TeX",
      html: true,
    });

  }

  async function convert(line) {
    var re = /\$(.*?)\$/;
    var match = re.exec(line)[0];
    var math = match.slice(1, -1);

    // ORIGINAL CODE
    // let result = await MJ(math).then(function(data){return line.replace(match,data.html);});
    // return result;

    let result = await MJ(math);
    console.log(`MJ is ready: ${result.html}`);
    return line.replace(match, result.html);
  }

  function format(line) {
    if(line.indexOf("$")>-1){
      line = convert(line).then( function(result) {
        console.log(result);
        return result;
      });

      console.log(line);
    }

    // additional formatting going below that needs to wait for the mathjax conversion
  }

Error output (partially truncated)

(node:17104) DeprecationWarning: Mongoose: mpromise (mongoose's default promise
library) is deprecated, plug in your own promise library instead: http://mongoos
ejs.com/docs/promises.html
Promise { <pending> }
TypeError: line.indexOf is not a function
    at emphasis (C:\something\routes\index.js:91:18)
    at format (C:\something\routes\index.js:139:12)
    at C:\something\routes\index.js:803:25
    at newTickHandler (C:\something\node_modules\m
promise\lib\promise.js:234:18)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
MJ is ready: <span class="mjx-chtml"><span class="mjx-math" etc.
<span class="mjx-chtml"><span class="mjx-math" etc.

Where format(lines[x]) is being called

Warning: not the prettiest code. Without going into too much detail I have "Modules" which consist of "Snippets" which contain text which I need to group together to form one coherent text.

lines[x] consists of strings that may look like this: "Einstein showed that $E = mc^2$."

app.get('/flashcards/module/:id', isAuthenticated, function(req, res){
    var moduleid = new ObjectId(req.params.id);
    var user = new ObjectId(req.session.user);
    var categoryid = new ObjectId(req.query.categoryid);
    var back = "";
    var html, lines;
    var index = 0;
    var indexoflastline = 0;
    var active = false;
    var moduletitle = "";

    Modules.findOne( { _id: moduleid } )

    .then(function(module) {
      moduletitle = module.title;
      return Snippets.find( { _id: module.snippets } ).sort({order: 1})
    })

    .then(function(snippets){

      if(snippets){

        for (var i = 0; i < snippets.length; i++) {
          if(snippets[i].suppresstext == true) {
            snippets.splice(i,1);
            i-=1;
          }
        }

        html = "<ul>";

        for(var i = 0; i < snippets.length; i++) {

          if(i==0) {
            lines = snippets[i].main.split('\n').clean('');

            for(var x = 0; x < lines.length; x++){
              if(checkindex(lines[x])==indexoflastline) {
                html += "<li>";
                html += format(lines[x]);
                html += "</li>";
              } else if (checkindex(lines[x])>indexoflastline) {
                html += "<ul>";
                html += "<li>";
                html += format(lines[x]);
                html += "</li>";
                indexoflastline += 1;
              } else if (checkindex(lines[x])<indexoflastline){
                html += "</ul>".repeat(indexoflastline-checkindex(lines[x]));
                html += "<li>";
                html += format(lines[x]);
                html += "</li>";
                indexoflastline -= indexoflastline-checkindex(lines[x]);
              }
            }

            indexoflastline = -1;
          }

          if(i>0){
            if(snippets[i].main!=snippets[i-1].main){

              html += "</ul>".repeat(indexoflastline+1);
              lines = snippets[i].main.split('\n').clean('');

              if(lines) {
                for(var x = 0; x < lines.length; x++){
                  if(checkindex(lines[x])==indexoflastline+1) {
                    html += "<li>";
                    html += format(lines[x]);
                    html += "</li>";
                  } else if (checkindex(lines[x])>indexoflastline+1) {
                    html += "<ul>";
                    html += "<li>";
                    html += format(lines[x]);
                    html += "</li>";
                    indexoflastline += 1;
                  } else if (checkindex(lines[x])<indexoflastline+1){

                    html += "</ul>".repeat(indexoflastline+1-checkindex(lines[x]));
                    html += "<li>";
                    html += format(lines[x]);
                    html += "</li>";
                    indexoflastline = indexoflastline-checkindex(lines[x]);
                  }
                }

              // indexoflastline = -1;
              }
            } else if (snippets[i].main==snippets[i-1].main){
              // index of snippet from previous snippet
              lines = snippets[i-1].subinformation.split('\n').clean('');
              indexoflastline = checkindex(lines[lines.length-1]);

              if(indexoflastline===undefined)
                indexoflastline = -1;

              indexoflastline = checkindex(lines[lines.length-1])+1 ? checkindex(lines[lines.length-1]) : -1;
            }
          }

          lines = snippets[i].subinformation.split('\n').clean('');

          if(lines){

            for(var x = 0; x < lines.length; x++){
              if(indexoflastline==-1) {
                html += "<ul>";
                html += "<li>";
                html += format(lines[x]);
                html += "</li>";
                indexoflastline = 0;
              } else if(checkindex(lines[x])==indexoflastline) {

                html += "<li>";
                html += format(lines[x]);
                html += "</li>";
              } else if (checkindex(lines[x])>indexoflastline) {

                html += "<ul>";
                html += "<li>";
                html += format(lines[x]);
                html += "</li>";
                indexoflastline += 1;
              } else if (checkindex(lines[x])<indexoflastline){
                html += "</ul>".repeat(indexoflastline-checkindex(lines[x]));
                html += "<li>";
                html += format(lines[x]);
                html += "</li>";
                indexoflastline -= indexoflastline-checkindex(lines[x]);
              }

              if(x==lines.length-1 && i < snippets.length-1) {
                if (snippets[i].main == snippets[i+1].main){
                  indexoflastline = checkindex(lines[x]);
                } else if (x==lines.length-1) {
                  html += "</ul>".repeat(indexoflastline+1);
                  indexoflastline = -1;
                }
              }
            }
          } else if (snippets[i].main == snippets[i+1].main) {
            if(x==lines.length-1 && i < snippets.length-1) {
              indexoflastline = checkindex(lines[x]);
              if (x==lines.length-1) {
                html += "</ul>".repeat(indexoflastline+1);
                indexoflastline = -1;
              }
            }
          }
        }

      if(i == snippets.length-1){
        for(var z = indexoflastline; z > 0; z--)
          html +="</ul>";
      }

      html += "</ul>"

      html += "</br>".repeat(2);

    return Categories.findOne( { _id: categoryid } );
  })

  .then(function(category) {
    back = `/flashcards/${category.parent}`;
    return userCategories.findOne( { category: categoryid, user: user } );
  })

  .then(function(userCategory) {
    res.render('user/flashcards/module', {
      moduleid: moduleid,
      moduletitle: moduletitle,
      back: back,
      htmlstring: html,
      selected: userCategory.active,
      admin: req.session.admin,
      categoryid: categoryid
    });

    return true;
  })

  .catch(function(err){
    if(err)
      return console.log(err);
  });
});

Instead of the mixing await and Promise, try it like this. Is the debug line printed correctly?

let data = await MJ(math);
console.log("MJ is ready: ${data}");
return line.replace(match, data.html);

You're mixing promises and await . Don't to that. You can't understand your own code. Here is your bug:

line = convert(line).then( function(result) {
        console.log(result);
        return result;
      });
console.log(line); // This is called before convert() finishes, of course it's a pending promise. 

Either use = with await , or use a promise and use the return value in the then resolution.

line = await convert(line);
console.log(line); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM