按顺序调用javascript代码的替代方法,其间有延迟

use*_*486 4 javascript timedelay settimeout node.js

我最初在python中有这个代码.

SendSerialPortCommand("XXX")
time.delay(0.5)
SendSerialPortCommand("YYY")
Run Code Online (Sandbox Code Playgroud)

我将此代码转换为node.js,但代码看起来更加丑陋.

SendSerialPortCommand("XXX");

setTimeout(function () {
    SendSerialPortCommand("YYY");
}, 500);
Run Code Online (Sandbox Code Playgroud)

想象一下,如果我的python代码看起来像这样.

SendSerialPortCommand("XXX")
time.delay(0.5)
SendSerialPortCommand("YYY")
time.delay(0.5)
SendSerialPortCommand("AAA")
time.delay(0.5)
SendSerialPortCommand("BBB")
Run Code Online (Sandbox Code Playgroud)

node.js代码setTimeout()在内部看起来很难看setTimeout().

如何在可读性方面改进node.js代码?我不关心违反这个问题的javascript的异步性质.重要的是可读性.

Far*_*ide 5

1.单线解决方案:

以前接受的解决方案 只会使事情复杂化,而不会带来任何可读性或改进.那样做,只需一行:

setTimeout(function(){ SendSerialPortCommand("XXX"); }, 500);
setTimeout(function(){ SendSerialPortCommand("YYY"); }, 1500);
setTimeout(function(){ SendSerialPortCommand("ZZZ"); }, 2000);
Run Code Online (Sandbox Code Playgroud)

2.简单的可配置解决方案:

如果你想让它可配置,将选项移到上面的配置,并在循环中调用,类似:

var schedulerData = [
   {delay: 500,  params: "XXX"},
   {delay: 1500, params: "YYY"},
   {delay: 2000, params: "ZZZ"}
];

for (var i in schedulerData) {
    var doTimeout = function(param, delay) {
        setTimeout(function(){ SendSerialPortCommand(param); }, delay );
    };
    doTimeout(schedulerData[i].params, schedulerData[i].delay);
}
Run Code Online (Sandbox Code Playgroud)

这是JSFiddle,可以玩.

3.使用节点模块 node-fibers

如果您希望通过node.js的高级解决方案"炫耀",您可以继续使用node-fibers,并在他们的手册中创建睡眠功能.

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    SendSerialPortCommand("XXX");
    sleep(1000);
    SendSerialPortCommand("YYY");
}).run();
console.log('still executing the main thread');
Run Code Online (Sandbox Code Playgroud)

node-fibers实施正在大量其他较小的库中使用,类似于WaitFor.更多信息可以在这里找到.

4.使用Promise&DeferredObjects

您可以创建基于Promise的超时功能.Joe描述了一种可能的实现方式.但是我将使用DefferredjQuery 提供小代码片段,以便更容易理解它的实际工作原理:

function wait(ms) {
    var deferred = $.Deferred();
    setTimeout(deferred.resolve, ms);
    // We just need to return the promise not the whole deferred.
    return deferred.promise();
}

// Use it
wait(500).then(function () {
    SendSerialPortCommand("XXX");
}).wait(500).then(function () {
    SendSerialPortCommand("YYY");
});
Run Code Online (Sandbox Code Playgroud)

如果承诺不支持,你将需要得到polyfillsECMAScript的,例如从公司承诺core-js或其他任何独立组件的承诺/ A +实现.

Deffered,也可以作为单独Deffered的NPM包,这个概念在这里很好地描述.