【问题标题】:NodeJS response.end when promise finish承诺完成时的NodeJS response.end
【发布时间】:2020-07-12 18:53:01
【问题描述】:

我在处理 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;
      }
    }

});

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    你可以试试这个吗?

    替换:

    $("*").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());
    

    【讨论】:

    • 我还添加了异步到 req.on('end',async () => {
    【解决方案2】:

    在解决承诺之前返回您的响应。使用 Promise.all() 等到 promise 解决后再发送响应

    你可以这样做。

    const promiseArray = [];
           
     $("*").each(async function(){
        if($(this).is("p,h1,h2,h3,h4,h5,h6,li,blockquote")){
            var toBeTranslated = $(this)[0].outerHTML;
    
            // push the promises to the array
            promiseArray.push(GoogleTranslateText(toBeTranslated));
         }
        });
        
       Promise.all(promiseArray).then(res=>{
          // Do the replacement and then send the response
            translated = el.getElementsByTagName( 'body' )[0].innerHTML;
            res.writeHead(200, 'OK', { 'Content-Type': 'text/plain; charset=utf-8'});
            res.end(translated);
        }) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 2022-11-06
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 2019-09-29
      相关资源
      最近更新 更多