数据在节点请求功能之外不可见



我正在编写带有Node(Express)从列表中搜索URL的小废料工具。问题在于访问forEach循环中请求回调函数之外的搜索结果。请帮助 - 为什么结果数组在请求之外为空?我想将此结果导出到视图。此外,在请求内部定义的任何变量都不会从外部定义。这是我的代码:

var express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var fs = require("fs");
var app     = express();

app.get('/scrap/',function(req,res){
    res.render('start.ejs');
});
app.post('/scrap/result', urlencodedParser, function(req,res){
        var lista = req.body.lista;
        var phrase = req.body.phrase;        
        var l = lista.split('n');
        var results = [];  // declaring results array       
        l.forEach(function(elem) {            
            request(elem, function(error, response, html) {
                try {
                if (html.indexOf(phrase) > 0) {
                var result = 'Phrase "' + phrase + '" found';
                }
                else {
                  var result = 'Phrase "' + phrase + '" not found';
                }                
              }
              catch(err) {
                var result = 'Error: '+ err.message;
              }
             results.push(result);             
             console.log(results) // here results array is filled with result
            });
           console.log(results); // results array is empty
        });  
         console.log(results); // results array is also empty
            res.render('result.ejs', { 
                  result : results[0],
                  phrase : phrase, 
            });     
}); 

app.use(function(req, res, next){
    res.redirect('/scrap');
});
app.listen(3000);

而不是forEach使用map,并返回一个承诺数组,然后在提供响应之前对所有承诺进行qait。

var responsePromises = l.map(geturslResponsePromise)
q.all(responsePromises).then(function(results){
     res.render('result.ejs', { 
         result : results[0],
         phrase : phrase, 
     });     
})

其中geturslResponsePromise是大意

var geturslResponsePromise = function(elem) {
   return new Promise(function(resolve, reject){
     request(elem, function(error, response, html) {
        try {
            if (html.indexOf(phrase) > 0) {
                resolve('Phrase "' + phrase + '" found');
            }
            else {
                resolve('Phrase "' + phrase + '" not found');
            }                
        }
        catch(err) {
            reject('Error: '+ err.message);
        }
    }) // request
   }) // promise
}

注意:未经测试的代码,可能是大量的错误,但这是我使用基于 ES5 的语法会采用的方法

note2:我还会推荐更有意义的变量名。 像请求,响应,URL,Uri这样的东西在网络空间中是相当众所周知的和底层的

最新更新