javascript - Nodejs通过回调方法发送ajax给客户端

标签 javascript jquery node.js ajax

我正在编写一个基于浏览器并在后端使用 Nodejs 的 Cmus Remote。该应用程序的一部分涉及获取当前播放的歌曲并将其显示给用户。

目前,它成功运行命令,将输出正确存储到变量中,但客户端请求在服务器端函数回调之前运行,因此它会重新运行歌曲的空字符串。

下面的代码可以更好地说明我的意思:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cmus Remote</title>
    <script src="client.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body id="body">

</body>
</html>

client.js

"use strict";
window.onload = function () {
    $.get("/songInfo", function(string){
        alert(string);
    });
};

server.js

var express = require('express');
var app = express();
var path = require('path');
var exec = require('child_process').exec;
var fs = require('fs');
var child;


var getSongCommand = "cmus-remote -Q | sed -n -e 's/^.*tag title //p'";
var getAlbumCommand = "cmus-remote -Q | sed -n -e 's/^.*tag album //p'";
var getArtistCommand = "cmus-remote -Q | sed -n -e 's/^.*tag artist //p'";

var song ="";
var album= "";
var artist = "";

app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res){
    res.sendFile(path.join(__dirname + '/index.html'));
});


app.get('/songInfo', function(req, res){
    updateSongInfo(getSongCommand);
    updateSongInfo(getAlbumCommand);
    updateSongInfo(getArtistCommand);

    var strings = [song, artist, album];

    res.send(strings);

});

var server = app.listen(8080, function () {
    console.log("Server online");
});

function updateSongInfo(command){
    var exec = require('child_process').exec;
    exec(command, function(error, stdout, stderr){
        callback(command, stdout);
    });
}


function callback(commandRan, output){
    console.log("Commandran = " + commandRan);
    console.log("Command output = " + output);
    if(commandRan.includes("title")){
        console.log("Updating song to " + output);
        song = output;
    }
    if(commandRan.includes("album")){
        album = output;
    }
    if(commandRan.includes("artist")){
        artist = output;
    }

    // console.log("In callback");
    // console.log(output);
    return output;
}

总而言之,ajax 响应工作正常,命令运行正常,并且值被保存到我拥有的 3 个全局变量中,但我不确定如何设置变量完成后 ajax 请求返回的时间值。

最佳答案

问题是因为 exec 是异步的,所以 exec 将被调用,程序将继续并将仍然为空的数据返回给调用者,然后它将以现在收到的执行数据完成。

要解决此问题,您可以使用 Promise 和 async/await。

app.get('/songInfo', async function(req, res){
    await updateSongInfo(getSongCommand);
    await updateSongInfo(getAlbumCommand);
    await updateSongInfo(getArtistCommand);

    var strings = [song, artist, album];

    res.send(strings);

});

...

function updateSongInfo(command){
    return new Promise((resolve, reject) => {
        var exec = require('child_process').exec;
        exec(command, function(error, stdout, stderr){
            callback(command, stdout);
            return resolve();
        });
    });
}

在Promise中调用resolve()将完成它,而调用reject()将抛出错误。您也可以为这些函数提供参数。

关于javascript - Nodejs通过回调方法发送ajax给客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46356429/

相关文章:

javascript - 我可以在 xampp (localhost) 中运行我的项目,但即使在配置后尝试在另一台计算机中运行时我也无法运行

javascript - 一次只允许显示一个幻灯片切换 div

javascript - 如果原始 src 无法加载内容且超时,iframe 使用替代图像

jquery - 如何用jQuery打开后隐藏相同的内容?

javascript - 调用类方法时“This”未定义

javascript - 将时间戳从时区转换为 UTC 时间戳?

javascript - 如何将单击时的图像源更改为一个源,并在同一单击时返回到不同的源

javascript - 如何处理可排序 Accordion 中的项目释放事件?

javascript - 如何获取号码的最后一位

node.js - socket.io 连接上的多次握手