我尝试使用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。

是什么引起错误“无法读取未定义的属性'应用'”?以及如何解决?

最佳答案

首先,您必须将一个函数传递给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()的地方。

关于node.js - 在q(promise)中,无法读取未定义的属性“apply”吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44741754/

10-12 15:36