我尝试使用nodejs的q库,我使用Q.fcall然后出现以下错误。
file_path/node_modules/q.js:155
throw e;
^
TypeError: Cannot read property 'apply' of undefined
at Promise.apply (/Users/name/Desktop/Programming/video_tutorial_archive/node_modules/q/q.js:1185:25)
at Promise.promise.promiseDispatch (/Users/name/Desktop/Programming/video_tutorial_archive/node_modules/q/q.js:808:41)
at /Users/name/Desktop/Programming/video_tutorial_archive/node_modules/q/q.js:1411:14
at runSingle (/Users/name/Desktop/Programming/video_tutorial_archive/node_modules/q/q.js:137:13)
at flush (/Users/name/Desktop/Programming/video_tutorial_archive/node_modules/q/q.js:125:13)
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
以下是我的代码:
app.get('/',function(req,res){
Q.fcall(sql_query.select_comment(con,comment))
.then(function(){
var deferred=Q.defer();
con.query("SELECT * FROM "+table_video, function (err, result) {
console.log("step 2 finished");
console.log("comment is "+comment);
// if (err) throw err;
query_result=result;
// deferred.resolve();
// console.log(query_result);
})
// return deferred.promise;
}).then(function(){
console.log("step 3 finished");
console.log("comment is "+comment);
console.log(query_result);
res.render('index',{
result:query_result,
comment:comment.comment
});
}).done();
});
我可以用Q.defer解决它,但我想用fcall代替。它更干净,没有所有deferred.promise和deferred.resolve。
是什么导致错误“无法读取属性'应用'未定义”?以及如何解决它?
答案 0 :(得分:2)
首先,你必须将一个函数传递给Q.fcall()
。您正在传递sql_query.select_comment(con,comment)
的返回结果,而这显然不是函数。
要使用Q.fcall()
更正,您将第一个参数作为要调用的函数传递,并且以下参数是您要传递给该函数的参数。此外,如果您希望select_comment
仍然绑定到sql_query
(我不知道是否需要),那么您可以使用.bind()
来保证安全。你可以像这样把所有这些放在一起:
Q.fcall(sql_query.select_comment.bind(sql_query), con, comment)
您获得的错误Cannot read property 'apply' of undefined
是因为sql_query.select_comment()
的返回值为undefined
所以当Q.fcall()
尝试在其上使用.apply()
附加参数时,它会引发错误。
您还有另一个错误,即您的外部承诺不等待con.query("SELECT * FROM "+table_video, function (err, result) {})
完成。最好的解决方案是只使用所有数据库功能的promise接口。然后,您可以从con.query()
处理程序中返回.then()
的承诺,它将自动链接到父承诺,事情将正确排序。
要亲自了解Q.fcall()
内部的内容,您可以查看该功能的来源here on Github:
Q.fcall = function (object /* ...args*/) {
return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
};
这最终会尝试在.apply()
的第一个参数上调用Q.fcall()
。
答案 1 :(得分:0)
我认为你应该将params分开:Q.fcall(sql_query.select_comment, con, comment)
,就像你对sql_query.select_comment.call(this, con, comment)
找不到.apply()
,因为sql_query.select_comment(con, comment)
的返回值不是函数。