Node.js JavaScript 片段中的跳过代码

Posted

技术标签:

【中文标题】Node.js JavaScript 片段中的跳过代码【英文标题】:Skipped Code in Node.js JavaScript Snippet 【发布时间】:2014-01-25 21:04:44 【问题描述】:

我列出了一些代码:

function write_to_orchestrate(data_to_write) 

    console.log('more testing');

    db.put('musician', '1', '"test":"test1"')
        .then(function (result) 
            res.send(result);
        )
        .fail(function (err) 
            res.send(err);
        );

    console.log('something');


看来,即使我在 db.put 函数调用的 .then 和 .fail 中的 res.send() 函数调用上有断点,它也不会停止其中任何一个。然而,console.log('more testing');和 console.log('something');正确到达。

我正在使用 Webstorm,但即使我只是使用终端和文本编辑器定期执行此代码,似乎 db.put(...) 的代码只是以某种方式被跳过。有关其他故障排除/调试的任何想法?

我还注意到,此调用发出 put 的数据源也是活动的并接受命令。只是为了确保我发出了几个 curl 命令并确保数据正常输入和输出。

这是一个视频,解释了发生了什么: http://youtu.be/CKq69z4ml8o

更新 #1: 我还尝试按照将 '"test":"test1"' 设置为 "test":"test1" 的建议,这似乎是个好主意,但不行。

更新 #2: 根据@hafthor,我尝试了另一个建议并实现了这样的代码以消除可能的分号问题。

function write_to_orchestrate(data_to_write) 

    console.log('more testing');

    db.put('musician', '1', "test":"test1").then(function (result)res.send(result);).fail(function (err) res.send(err););

    console.log('something');


它仍然没有,但我确实在 WebStorm 中运行代码和调试时发现代码到达了 db.put,但后来我尝试进入代码,它直接进入 .fail,然后跳过并在 console.log('something'); 结束行。

另外,还有一个视频可以让您尝试更多地尝试使其工作:http://www.youtube.com/watch?v=rItBhyfG5AY

【问题讨论】:

您将数据发送到远程数据库正确吗?该数据库是否正常工作? then/fail 函数仅在知道结果后才执行。也许远程机器需要很长时间才能响应。 添加了对问题的更新以阐明远程数据库的状态。好问题。 你的程序在puts发生之前就退出了吗?没有更多上下文很难判断,但如果此模块直接执行然后退出,则事件队列可能永远无法运行这些异步放置。 【参考方案1】:
    您未能明确说明您正在使用的数据库模块。根据上下文线索,它看起来像 this orchestrate module,对吗? 我的 youtube!将您的代码放入您的问题中。包括您在哪里初始化db,这是最重要的部分,它允许您通过更改您在此处发布的文本来隐藏您的令牌……您要么想要删除这些视频,要么更改您的令牌,您在第一个视频中,我已经无可救药地危及了您的安全。是的,它很模糊,但不是那么模糊。

好的,您的第一个故障排除步骤是创建一个简化的脚本。我的猜测是您以某种方式错误地使用了该模块。试试这个:

var db = require('orchestrate')('SUPER SECRET TOKEN THAT SHOULD NOT BE IN A YOUTUBE VIDEO');

console.log('before query');
db.put('musician', '1', test: 'test1')
    .then(function (result) 
        console.log('THEN!!!');
        console.log(result);
    )
    .fail(function (err) 
        console.log('FAIL!!!');
        console.log(err);
    );
console.log('after query');

...在这里我希望您注意几件重要的事情:

隐藏你的令牌(说真的,隐藏你的令牌) 我正在根据我链接的模块的文档工作,但如果您使用不同的东西或以任何方式对其进行了修改,那么所有这些建议都是可疑的 根据@nhaa123s 的评论和文档,该值是对象文字,而不是 JSON 字符串,所以我进行了调整 根据链接的文档,musician 是集合名称,1 是您要设置的键(这似乎是一个奇怪的键名,但无论如何),而 test:'test1' 是你为你的价值而使用的数据结构。我从未使用过编排,如果需要,请确保您已正确初始化 musician,并请确认它将支持严格的数字键,例如 1(或者,更好的是,使用更传统的键类型喜欢testkey) 我使用了 console.log,因此您可以更简单地确认回调正在执行。

...您可能会看到几种不同的结果,具体取决于问题的实际位置。如果您正确使用数据库模块,那么您应该执行.then() 回调并知道问题在于您如何将其合并到您的代码中。如果它失败并且您在控制台上收到失败消息,您将看到实际错误,这可能会引导您朝着正确的方向前进。如果您从不调用 .then().fail() 回调,则编排模块可能尚未准备好迎接黄金时段,或者您的依赖链中存在一些不兼容问题。

如果您可以成功执行该 sn-p,则下一步是将 db.put().then().fail(); 链复制到您的 write_to_orchestrate() 函数中而不进行任何修改,删除现有链。如果它仍然有效,那么您已经解决了您的数据库问题,如果没有,那么我的第一个猜测是某种范围问题,但是如果不查看更多代码就无法判断。

现在,我相信您的响应对象肯定存在范围问题,因此您从未发送任何内容。

将此添加到您的 write_to_orchestrate() 函数的顶部:

function write_to_orchestrate(data_to_write) 
    if (res === undefined) console.log("This is not the response you're looking for");
    else console.log("Just kidding, you're (probably) good");

    // etc.

如果您发现 res 在您的函数中不可访问,您只需要找到一种方法将其置于作用域内,或许可以将其与 data_to_write 一起发送:

function write_to_orchestrate(data_to_write, res) 
    if (res === undefined) console.log("The problem clearly exists even further up the chain");
    else console.log("Ah, just as we expected");

    // etc.

...这应该会让你走上正确的道路。

【讨论】:

这也让我朝着正确的方向前进。我也开始按照这些思路做一些 BDD/TDD,最后使用 done 为异步代码提供了一个简单的测试模式:***.com/questions/21175123/… 很高兴它有帮助:)【参考方案2】:

尝试将'"test":"test1"' 替换为"test":"test1"

【讨论】:

【参考方案3】:

只是想一想,您是否尝试过重载 db.put 函数?

var _put = db.put; db.put = function(a,b,c) console.log('yep'); return _put(a,b,c);

【讨论】:

试过了...还是不行。 :(【参考方案4】:

在观看您的第二个视频时,您似乎希望在您完成他们的任务时执行这些功能。 (例如47s into the second video)。您实际上在做的是分配 db.put 函数(a,b,c),而不是执行它。因此,正如您在视频中提到的那样,它跳过身体是有道理的。

但是,它最终应该执行它。它是否跳过了您放入的断点?

由于我对 Webstorm 一无所知,我认为让它破坏你的 then 和 fail 函数的最可靠方法是像这样放置明确的 debugger 语句:

function write_to_orchestrate(data_to_write) 

console.log('more testing');

db.put('musician', '1', '"test":"test1"')
    .then(function (result) 
        debugger;
        res.send(result);
    )
    .fail(function (err) 
        debugger;
        res.send(err);
    );

console.log('something');


然后通过原生节点debugger运行:

node debug yourapp.js

在调试器中,键入 C 继续,然后在遇到调试器语句时应该停止。

【讨论】:

是的。它似乎永远不会捕获任何 .then 或 .fail 代码。我知道 db.put 是非阻塞的,但我不知道为什么在那之后什么都没有发生。理论上,这两件事中的一件最终应该执行。对吗? 嗯,我不知道您使用的是哪个数据库模块,所以我不能说这是真的,但这是合理的。我用您可以尝试的替代调试测试更新了我的答案。【参考方案5】:

我不确定是否可以在没有更多关于程序其余部分的详细信息的情况下回答这个问题,但看起来这是一个经典的“为什么我的异步代码不能同步运行?”问题(SO 上有很多这样的问题 - here's the canonical example)。

db.put() 几乎可以肯定是异步的——看起来它返回一个promise,因此当你的异步数据库写入完成时,它将执行.then() 函数或.fail() 函数。这里要理解的关键是这些函数与其余代码不在同一个堆栈中执行 - 它们发生在未来某个未指定的时间,因此执行如下所示:

// initial stack
console.log('more testing');
db.put(...);
console.log('something');

// ... time passes, the call stack is cleared
// ... the database returns a status message
// new stack:
res.send(result);

我最好的猜测是:

    您的程序在数据库返回其状态消息之前退出,或者 您的程序仍在运行,但 res 已更改并且不再是可用的流,或者 您的数据库写入无声无息。

(2) 可以通过断点或回调中的console.log 调用来排除,看起来您已经尝试过了。 (3) 如果数据库模块稳定,则不太可能。 (1) 很难在不查看其余代码的情况下进行评估,但似乎最有可能。

如果您了解所有这些并期待异步回调,那么请不要介意。

【讨论】:

【参考方案6】:

如果this 是您正在使用的编排包,那么我看到它使用kew 作为其承诺管理器。这个包的文档建议使用.end() 来结束链thenfail 调用。通过快速测试,我可以看出,除非您在链的末尾添加此 .end() 调用,否则您将无法捕获某些类型的错误。所以尝试这样的事情:

db.put('musician', '1', '"test":"test1"')
    .then(function (result) 
        res.send(result);
    )
    .fail(function (err) 
        res.send(err);
    )
    .end(); /// <<< Add this at the end of your chain.

这可能会导致报告错误。

【讨论】:

【参考方案7】:

失败时的错误是什么? 这是哪个:https://docs.orchestrate.io/#errors?

您可以尝试使用诸如wireshark 之类的网络代理并观察网络流量吗?随put 请求一起发送的标头是什么?是否与您在此处看到的相符:https://docs.orchestrate.io/#key/value/put-(create/update)

【讨论】:

问题是它永远不会失败。错误被吞没了。

以上是关于Node.js JavaScript 片段中的跳过代码的主要内容,如果未能解决你的问题,请参考以下文章

如何从node js文件中调用一个vanilla JavaScript函数?

Spring Batch 中的跳过是如何实现的?

使用FilterInputStream的跳过方法

你可能不知道的JavaScript代码片段和技巧(下)

你可能不知道的JavaScript代码片段和技巧(上)

python nose测试框架全面介绍十---用例的跳过