了解示例异步调用javascript

时间:2018-03-14 19:17:36

标签: javascript asynchronous

我正在“玩”javascript上的异步调用,我试图让下一个示例工作,但不能:

// calls function f on next event loop
function callAsync(f, ...args) {
    setTimeout(() => f(...args), 0);
}

var f = (a, b, cb) => cb(null, a + b);

f2 = () => {
    a = 2;
    b = 3;

    setTimeout(() => 
    f(a, b, (err, res) => {
        if (!err) console.log(res);
    }), 0);

    callAsync(f, a, b, (err, res) => {
        if (!err) console.log(res);
    });

    a = 10;
    b = -10;
}

f2();

所以,通过运行它,你得到的结果是:

0
5

为什么callAsync不起作用 - 这是我的问题!

3 个答案:

答案 0 :(得分:3)

不同之处在于评估ab的时间。将闭包传递给setTimeout时,在执行使用它们的闭包时 - 在重新分配它们之后,变量将被读取。当您将ab传递给callAsync时,会立即将其作为通话的一部分进行评估。 callAsync内的关闭只会看到值args = [2, 3, (…)=>{…}]

答案 1 :(得分:1)

这可能会说清楚。这里,大概是采取的步骤:

        define callAsync
        define f
        define f2
        f2()
          a = 2
          b = 3
 +------- setTimeout(() => f(a, b, callbackFn1), 0)
 |        callAsync(f, 2, 3, callbackFn)
 | +------- setTimeout(() => f(2, 3, callbackFn2), 0)
 | |      a = 10
 | |      b = -10
 | |    end f2
 +----> f(10, -10, calllbackFn1)
   |      callbackFn1(null, 10 + -10)
   |        if (!err) console.log(res)
   |          console.log(0)                     //~> 0
   |    end f
   +--> f(2, 3, callbackFn2)
          callbackFn2(null, 2 + 3)
            if (!err) console.log(res)
              console.log(5)                     //~> 5
        end f

答案 2 :(得分:1)

您的callAsync完全异步,但在您致电a时会复制bcallAsync的值。它相当于:

setTimeout((a,b) => 
f(a, b, (err, res) => {
    if (!err) console.log(res);
}), 0, a, b);

要实现您想要的目标,您可以使用一个对象,因为它们是引用类型,当您将它们作为参数传递时,它们不会被复制:



// calls function f on next event loop
function callAsync(f, ...args) {
    setTimeout(() => f(...args), 0);
}

var f = (data, cb) => cb(null, data.a + data.b);

var data = {
  a: 2,
  b: 3,    
};

callAsync(f, data, (err, res) => {
    if (!err) console.log(res);
});

data.a = 10;
data.b = -10;