首页 > 解决方案 > 承诺完成时的NodeJS response.end

问题描述

我在处理 nodeJS 中的 Promise 时遇到了困难。

我想要完成的是使用 Google Translate API 翻译 HTML 页面。HTML 文档被发送到我的 nodeJS 服务器。我使用 jquery 将每个块发送到 API,然后替换翻译的内容。

问题是服务器在翻译内容之前返回响应,因为对 API 的调用是异步的。

我需要翻译它,替换它,然后才返回内容。

我的非工作代码如下:

var StringDecoder = require('string_decoder').StringDecoder;
var http = require('http');
const {TranslationServiceClient} = require('@google-cloud/translate');
var testStr;

var httpServer = http.createServer((req, res) => {
    var decoder = new StringDecoder('utf-8');
    
    let buffer = '';
    req.on('data', (chunk) => {
        buffer += decoder.write(chunk);
    });
    
    req.on('end', () => {
        buffer += decoder.end();
        testStr = buffer;
        var jsdom = require("jsdom");
        var { JSDOM } = jsdom;
        var myhtml = "<!DOCTYPE html><html><head><title>titleTest</title></head><body>"+testStr+"</body></html>";
        var { window } = new JSDOM( myhtml );
        var $ = require( "jquery" )( window );
        el = window.document;
        
        $("*").each(async function(){
            if($(this).is("p,h1,h2,h3,h4,h5,h6,li,blockquote")){
                var toBeTranslated = $(this)[0].outerHTML;
                var translatedChunk = await GoogleTranslateText(toBeTranslated);
                $(this).replaceWith(translatedChunk);
            }
        });
        
        translated = el.getElementsByTagName( 'body' )[0].innerHTML;
        res.writeHead(200, 'OK', { 'Content-Type': 'text/plain; charset=utf-8'});
        res.end(translated);
    });
    
    async function GoogleTranslateText(toBeTranslated) {
      // Construct request
      const request = {
        parent: `projects/${projectId}/locations/${location}`,
        contents: [toBeTranslated],
        mimeType: 'text/html', // mime types: text/plain, text/html
        sourceLanguageCode: 'en',
        targetLanguageCode: 'pl',
      };

      try {
        // Run request
        const [response] = await translationClient.translateText(request);

        for (const translation of response.translations) {
          return translation.translatedText;
        }
      } catch (error) {
        console.error(error.details);
        return false;
      }
    }

});

标签: javascriptnode.js

解决方案


你能试试用这个吗?

代替:

$("*").each(async function(){
            if($(this).is("p,h1,h2,h3,h4,h5,h6,li,blockquote")){
                var toBeTranslated = $(this)[0].outerHTML;
                var translatedChunk = await GoogleTranslateText(toBeTranslated);
                $(this).replaceWith(translatedChunk);
            }
        });

与以下:

await Promise.all($("*").map(async function(){
   if($(this).is("p,h1,h2,h3,h4,h5,h6,li,blockquote")){
       var toBeTranslated = $(this)[0].outerHTML;
       var translatedChunk = await GoogleTranslateText(toBeTranslated);
       $(this).replaceWith(translatedChunk);
   }
}).get());

推荐阅读