诺兰';s承诺/A+;JavaScript难题

诺兰';s承诺/A+;JavaScript难题,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,我已经阅读了Nolan Lawson的几篇文章,但仍然对JavaScript中的承诺有一些疑问。在诺兰的帖子末尾,你可以找到四个谜题的答案(我在这里附上了截图) 因此,我有几个问题: 为什么第一个谜题中的doSomethingElse()函数有未定义的值?在我看来,它一定有resultOfDoSomething类似于第四个拼图 第三个和第四个拼图有什么区别?在第一个的第三个拼图中,然后我们写doSomethingElse(),在第四个拼图中,我们只写函数名,doSomethingElse。怎么可

我已经阅读了Nolan Lawson的几篇文章,但仍然对JavaScript中的承诺有一些疑问。在诺兰的帖子末尾,你可以找到四个谜题的答案(我在这里附上了截图)

因此,我有几个问题:

  • 为什么第一个谜题中的
    doSomethingElse()
    函数有
    未定义的值?在我看来,它一定有
    resultOfDoSomething
    类似于第四个拼图

  • 第三个和第四个拼图有什么区别?在第一个
    的第三个拼图中,然后
    我们写
    doSomethingElse()
    ,在第四个拼图中,我们只写函数名,
    doSomethingElse
    。怎么可能呢?在第四个谜题的
    中,doSomethingElse真正做了什么

  • 为什么第三个拼图中的
    doSomethingElse()
    函数与
    doSomething
    同时启动

  • 为什么第一个谜题中的doSomethingElse()函数有未定义的值?在我看来,这一定是第四个谜题的结果

    doSomething
    的预期结果被传递给匿名函数(该函数甚至不接受参数)。因此,无论通过什么,都会丢失。调用
    doSomethingElse
    时不带任何参数,因此第一个函数参数是
    undefined

    第三个和第四个拼图有什么区别?在第三个拼图中,我们先写doSomethingElse(),在第四个拼图中,我们在这里只写函数名-doSomethingElse。怎么可能呢?在第四个谜题中,doSomethingElse到底做了什么

    JavaScript中的函数是可以随意传递的对象。这实际上就是整个回调传递的工作原理:有一个函数(这里是
    然后
    )将函数作为参数,然后调用该参数

    因此,在后一个代码中,传递给
    然后
    的函数是
    doSomethingElse
    ,这就是后来调用的函数。但在前者中,我们直接调用
    doSomethingElse
    (带括号
    ()
    )。因此传递给
    的是该函数的返回值,该函数不太可能是一个一旦承诺完成就可以计算的函数

    为什么第三个拼图中的doSomethingElse()函数与doSomething函数同时启动

    正如我所说,在调用
    doSomething
    的同时,会立即调用该函数。只有返回值被传递到
    然后
    ,一旦承诺解决,就会调用该值

  • 为什么
    doSomethingElse()
    在第一个谜题[获得通过]
    未定义中起作用
  • 让我们看一个更简单的例子:

    foo();   // Line #1
    foo(42); // Line #2
    
    这两条线的区别是什么?在第1行,我们调用foo,但不传递任何值(因此
    未定义
    ),而在第2行,我们调用foo,并传递它42

    回到岗位:

    doSomething().then(function () {
        return doSomethingElse( );
        //                     ^-- we are not passing a value
    }).then(finalHandler);
    
    这和第四个拼图有什么不同?在第四个谜题中,我们将函数的引用传递给
    ,然后传递给
    。向承诺提供对函数的引用,允许它稍后使用承诺的结果调用它


  • 第三个和第四个拼图有什么区别?在第三个拼图中[…]我们写
    doSomethingElse()
    ,在第四个拼图中我们写[…]
    doSomethingElse
  • 为了解释第三个和第四个谜题的区别,让我们看一些简单的例子。以下两行有何区别:

    var foo = function foo() {
        return 42;
    };
    var a = foo;   // line #1
    var b = foo(); // line #2
    
    在上面的代码段中,
    a
    将包含对函数
    foo
    的引用,而
    b
    将包含调用foo的结果(即42)


  • 为什么第三个拼图中的
    doSomethingElse()
    doSomething
    同时开始
  • 与第3个和第4个函数之间的区别类似,请注意使用
    ()
    调用该函数。这里我们调用了
    doSomething()
    doSomethingElse()
    ,而不是等待承诺“解决”(等待第一次调用完成)。在此之前,让我们逐步完成执行:

  • 执行返回承诺的
    doSomething
  • doSomethingElse()
    附加到承诺,但请稍候,
    doSomethingElse()
    正在调用
    doSomethingElse()
    ,因此这将异步发生,我们将把它返回的承诺附加到返回的承诺
    doSomething()
  • 将函数
    finalHandler
    附加到承诺中

  • 您必须注意:
    doSomethingElse
    是一个函数引用,而
    doSomethingElse()
    表示您立即“调用”该函数。在这里你可以得到函数的结果,如果有的话

    关于承诺,我理解:

    A) “then”方法获取上一次调用的结果,并将其作为参数传递给自己的参数(如果它是函数)

    B) 只有当“then”方法中的函数返回某些内容时,执行才会延迟

    在这些情况下,我们有:

    谜题1)ResultToDoSomething用作匿名函数的参数

    function (){ return doSomethingElse ();} 
    
    这将调用不带参数的
    doSomethingElse()

    谜题2)匿名函数不返回数据,因此立即执行下一个“then”

    谜题3)表达式
    doSomethingElse()
    是doSomethingElse调用的结果。这个值被用作“then”方法的参数,因为它不是一个函数(在本例中!),所以我们可以传递给另一个“then”

    finalHandler接收最后的有效结果作为参数,在本例中为ResultToDoSomething

    谜题4)每个“then”方法都接收到参数
    var foo = function foo() {
        return 42;
    };
    var a = foo;   // line #1
    var b = foo(); // line #2
    
    function (){ return doSomethingElse ();} 
    
    doSomething().then(function(resultOfDoSomething) {
    //               it's here: ^^^^^^^^^^^^^^^^^^^
        return doSomethingElse(  );
    //          but not there: ^^ - Ooops!
    });
    
    promise.then(function callback(res) {
        …
    });
    
    function callback(res) {
        …
    }
    promise.then(callback);
    
    var promise = doSomething();
    doSomethingElse();
    promise.then(finalHandler);