【问题标题】:How to use promises to return the final result of an array?如何使用 promise 返回数组的最终结果?
【发布时间】:2014-05-09 19:18:51
【问题描述】:

我目前正在尝试返回特定网站上所有文件名(在每个现有文件夹中)的请求。我的 Web 应用程序使用 NodeJS、Express、Cheerio 和 Request to Web scrape。我的代码首先获取所有文件夹名称的列表。在检索文件夹名称列表后,它会进入每个文件夹名称以获取文件名列表并将它们存储在“文件”数组中。最后,“文件”数组将被发送到客户端。

现在我对异步的东西有一个大问题,因为我的请求总是会返回一个空的“文件”列表。我安装了 Q 节点模块并尝试使用 Promise,但没有获得我想要的结果。我还是 nodeJS 的新手,如果有人可以帮助我,我会很高兴.. :)

exports.getAllImages = function(req, res) {
    var folders = [];
    var files = [];

    //Step 1: Get folder names and store all of them in the 'folders' array
    var foldersUrl = 'http://students.washington.edu/jmzhwng/Images/';
    request(foldersUrl, function(error, response, html){
        if(!error){
            var $ = cheerio.load(html);
        $("a:contains('-')").filter(function(){
            var data = $(this)[0].attribs.href;
            folders.push(data); 
        })

        //Step 2: Using the 'folders' array, get file names in each folder and store all of them in the 'files' array
        for (var i=0; i < folders.length; i++) {
            var imagesUrl = 'http://students.washington.edu/jmzhwng/Images/' + folders[i];
            request(imagesUrl, function(error, response, html){
                if(!error){
                    var $ = cheerio.load(html);
                    $("a:contains('.')").filter(function(){
                        var data = $(this)[0].attribs.href;
                        files.push(data);
                    })
                }
            })
        }

        //Step 3: Return all file names to client-side
        res.json({
            images: files
        }, 200);
        console.log('GET ALL IMAGES - ' + JSON.stringify(files));
    }
})

为了更好的可读性或支持,您可以在此处查看我创建的 JSFiddle:http://jsfiddle.net/fKGrm/

【问题讨论】:

    标签: javascript node.js request q cheerio


    【解决方案1】:

    您不一定需要为此做出承诺——如果没有承诺,您已经完成了 95% 的工作。我认为您知道的主要问题是您的响应是在图像请求返回之前发送的。您只需要等待这些完成后再发送响应。

    最基本的方法是计算您在第 2 步中收到的回调次数。当它等于folders.length 时,发送您的回复。

    这是一个简化的版本:

    var request = require('request'),
        cheerio = require('cheerio');
    
    var baseUrl = 'http://students.washington.edu/jmzhwng/Images/';
    
    var files = [];
    
    request(baseUrl, function (error, res, body) {
      var folders = folderLinks(cheerio.load(body));
          count = 0;
    
      folders.forEach(function (folder) {
        request(baseUrl + folder, function (error, res, body) {
          files.push.apply(files, fileLinks(cheerio.load(body)));
    
          if (++count == folders.length) {
            console.log(files);
          }
        });
      });
    });
    
    function folderLinks ($) {
      return $('a:contains(-)').get().map(function (a) {
        return a.attribs.href;
      });
    }
    
    function fileLinks ($) {
      return $('a:contains(.)').get().map(function (a) {
        return a.attribs.href;
      });
    }
    

    【讨论】:

    • 非常感谢您的帮助,托德!您的干净和简化版本完美运行。你太棒了!!!
    • 不客气!还有一件事:如果您在生产中使用它,请记住添加错误检查。为了清楚起见,我把它省略了。此外,如果您发现自己经常编写这种模式,请尝试 run-parallelbatch
    • 听起来不错!好吧,我会的。再次感谢你的帮助!为我节省了无数小时
    猜你喜欢
    • 1970-01-01
    • 2013-06-05
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2015-05-09
    • 2017-06-02
    相关资源
    最近更新 更多