gpt4 book ai didi

javascript - 如何在 NodeJS createServer 中调用模块函数

转载 作者:行者123 更新时间:2023-11-30 00:12:20 25 4
gpt4 key购买 nike

我有两个 js 文件 screenshot.js 和 main.js,我想从 screenshot.js 返回 JSON 到 main.js,但是当你运行 console.log( this.result) 你在控制台看到结果但是当你在 main.js 文件中调用它时结果是空的,如何解决这个问题。

这是我的代码。

截图.js

module.exports={
result: '',
run: function(url,w,h){
var phantom=require('phantom');
phantom.create().then(function(ph){
ph.createPage().then(function(page){
page.property('viewportSize',{width:w,height:h}).then(function(){
page.open('http://' + url + '/').then(function(status){
page.property('onLoadFinished').then(function(){
console.log(status);
if (!(status == 'success')){
this.result={'image':'no'};
this.result=JSON.stringify(this.result);
// console.log(this.result);
page.close();
} else {
this.result=page.renderBase64('jpeg').then(function(img){
this.result={'image': img};
this.result = JSON.stringify(this.result);
// console.log(this.result);
page.close();
});
}
});
});
});
});
});
return this;
},
get: function(){
return this.result;
}
}

主要.js

var http = require( 'http' );
var parsing = require( 'url' );
var screenshot = require( './screenshot' );
http.createServer( function( req, res ) {
var url, img, w, h, query_object, result;
url = req.url;
url = url.replace( '/', '' );
url = url.trim();
if ( !( url == 'favicon.ico' ) ) {
console.log( url );
query_object = parsing.parse( req.url, true ).query;
console.log( query_object );
res.writeHeader( 200, { "Content-Type": "text/html" } );
w = parseInt( query_object.width );
h = parseInt( query_object.height );
result = screenshot.run( url, w, h ).get();
console.log( result );
res.end();
}
}).listen( 80, '127.0.0.1' );

console.log( 'server isn running....' );

最佳答案

您的操作是异步的。在完成之前您无法获取结果。您在异步操作完成之前很久就调用了 .get()。您需要从 .run() 返回一个 promise 并使用 .then() 上,不将结果存储在实例数据中,无法判断它何时准备就绪。

作为一般规则,任何时候您在异步回调中获取结果并将其分配给某个更高范围的变量时,这是一个主要的警告信号,表明您可能做错了什么,因为更高范围的代码不知道该值何时有效。相反,您需要使用异步回调中的值,从该回调中调用某个函数并将该值传递给该函数,或者在 promise 中返回该值,以便调用者可以将其作为 promise 的已实现值使用(这就是我将您的代码更改为下面的内容)。

这是一个重写的版本,它返回一个 promise 并将结果作为 promise 的 fulfilled 值返回:

module.exports = {
run: function (url, w, h) {
var phantom = require('phantom');
return phantom.create().then(function (ph) {
ph.createPage().then(function (page) {
page.property('viewportSize', {
width: w,
height: h
}).then(function () {
page.open('http://' + url + '/').then(function (status) {
page.property('onLoadFinished').then(function () {
console.log(status);
if (status != 'success') {
page.close();
return JSON.stringify({'image': 'no'});
} else {
return page.renderBase64('jpeg').then(function (img) {
page.close();
return JSON.stringify({'image': img});
});
}
});
});
});
});
});
}
}

稍后,我会发布一个更好的写法,它不会使用太多的 promise 嵌套。

无需调用 .get(),您只需像这样使用返回的 promise:

var http = require( 'http' );
var parsing = require( 'url' );
var screenshot = require( './screenshot' );
http.createServer( function( req, res ) {
var url, img, w, h, query_object, result;
url = req.url;
url = url.replace( '/', '' );
url = url.trim();
if ( !( url == 'favicon.ico' ) ) {
console.log( url );
query_object = parsing.parse( req.url, true ).query;
console.log( query_object );
res.writeHeader( 200, { "Content-Type": "text/html" } );
w = parseInt( query_object.width );
h = parseInt( query_object.height );
screenshot.run( url, w, h ).then(function(result) {
console.log( result );
res.end();
});
}
}).listen( 80, '127.0.0.1' );

console.log( 'server isn running....' );

我自己没有办法对此进行测试,但这应该是您的 run() 方法的嵌套较少的版本。这在可能的情况下使用链接,只有在遵循 .then() 处理程序需要访问先前结果时才嵌套。

module.exports = {
run: function (url, w, h) {
var phantom = require('phantom');
return phantom.create().then(function (ph) {
return ph.createPage();
}).then(function (page) {
// nest other calls here so they all have access to the page argument
return page.property('viewportSize', {width: w, height: h }).then(function () {
return page.open('http://' + url + '/');
}).then(function (status) {
return page.property('onLoadFinished').then(function() {return status;});
}).then(function (status) {
console.log(status);
if (status != 'success') {
page.close();
return JSON.stringify({'image': 'no'});
} else {
return page.renderBase64('jpeg').then(function (img) {
page.close();
return JSON.stringify({'image': img});
});
}
});
});
}
}

注意:我认为您还缺少在出现错误时调用 page.close() 的错误处理。

这是一个为 closePage() 添加了错误处理的版本,因此无论何时打开一个页面,无论我们如何保留此代码,它都会关闭,即使发生错误也是如此:

module.exports = {
run: function (url, w, h) {
var phantom = require('phantom');
return phantom.create().then(function (ph) {
return ph.createPage();
}).then(function (page) {
var pageOpen = false;

function closePage(val) {
if (pageOpen) {
page.close();
}
return val;
}

// nest other calls here so they all have access to the page argument
return page.property('viewportSize', {width: w, height: h }).then(function () {
return page.open('http://' + url + '/');
}).then(function (status) {
pageOpen = true;
return page.property('onLoadFinished').then(function() {return status;});
}).then(function (status) {
console.log(status);
if (status != 'success') {
return JSON.stringify({'image': 'no'});
} else {
return page.renderBase64('jpeg').then(function (img) {
return JSON.stringify({'image': img});
});
}
}).then(function(closePage), function(err) {
closePage();
throw err;
});
}):
}
}

关于javascript - 如何在 NodeJS createServer 中调用模块函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35955570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com