【问题标题】:Unable to pass result of a function to global scope in node.js无法将函数的结果传递到 node.js 中的全局范围
【发布时间】:2016-12-02 20:54:48
【问题描述】:

我正在使用 node.js 的 images-scraper 包来搜索与给定搜索字符串相关的图像。包正确返回结果数组。我正在尝试将该数组的一个元素(图像的 url)传递给我可以通过全局范围在另一个包中使用的变量。

这是我的代码:

var Scraper = require ('images-scraper')
  , bing = new Scraper.Bing();

bing.list({
    keyword: 'search string here',
    num: 1,
    detail: true
})
.then(function (res) {
    console.log('url of image result', res[0]['url']);
    global.url_result = res[0]['url'];      
}).catch(function(err) {
    console.log('err',err);
})

console.log('array',global.url_result); 

该程序包有效 - 当被告知在函数内将图像打印到控制台时,控制台从 res[0]['url'] 返回图像的 URL,但是函数外部的控制台日志将 global.url_result 返回为未定义。关于如何在函数之外访问该结果的任何建议?如果我不应该使用全局范围,那么最好的方法是什么?提前致谢。

【问题讨论】:

    标签: javascript node.js scope web-scraping


    【解决方案1】:

    您的问题在于尚未设置全局。您的 bing.list(...).then(...) 返回一个承诺,因此是异步的。因此,您的全局尚未在范围之外声明。您可以告诉您的全局尚未声明,因为您的控制台日志发生的顺序不符合您的预期。尽管它们发生的顺序并非偶然,并且是创建承诺的方式,因此您需要了解更多有关它们的信息,以避免将来像您刚刚犯的错误一样。

    我会阅读 Promise herehere 和其他一些地方。

    但我会使用模块导出而不是设置全局变量,在我看来这是更好的做法。模块导出允许您将变量和函数从一个文件导出到另一个文件。它们设置为module.exports = myVariable。然后可以使用require 函数将它们拉入您服务器上的其他文件中。请注意,如果它是未安装 npm 的模块,则必须使用相对目录。相对路径以代表当前目录的点开头,然后遵循常规路径约定。

    在你的情况下我会这样做:

    文件image_scraper.js中的代码:

    var Scraper = require ('images-scraper')
      , bing = new Scraper.Bing();
    
    function scrapeBing (searchString) {
        return bing.list({
            keyword: searchString,
            num: 1,
            detail: true
        })
        .then(function (res) {
            console.log('url of image result', res[0]['url']);
            return res[0]['url']  
        }).catch(function(err) {
            console.log('err',err);
        })
    }
    
    module.exports = {
        bing: scrapeBing
    };
    

    app.js 文件中的代码(它与 image_scraper.js 位于同一目录中。您无需更改所需路径即可。)

    var imageScraper = require('./image_scraper');
    
    imageScraper.bing("Mario").then(function (url_result) {
        console.log("url_result", url_result);
    });
    

    【讨论】:

    • 这很好 - 感谢您花时间解释我的问题以及更好的方法。根本没有遇到模块导出,所以我会阅读这种方法
    • @Gideon 如果您对命令行感到满意,您可以尝试 nodeschool.io 的 learnyounode 教程。 nodeschool.io
    【解决方案2】:

    您正确设置了全局变量,但是您有操作顺序问题。您在 then 函数中设置 global.url_result ,因此它发生在承诺完成后,因此 console.log 在设置变量之前触发。如果您将日志包装在一个函数中,然后在 then 函数中调用它,那可以工作

    .then(function (res) {
        console.log('url of image result', res[0]['url']);
        global.url_result = res[0]['url'];      
        loggerFunc();
    }
    var loggerFunc() {
      console.log(global.url_result);
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 2018-09-02
      • 1970-01-01
      • 2020-04-26
      • 1970-01-01
      相关资源
      最近更新 更多