function.apply.bind如何在以下代码中工作?

Gwa*_*r17 11 javascript bind apply promise ecmascript-6

所以我得到了一个[200,599]的数组从promise返回,并且spread内的回调函数被传递给Function.apply.bind,但现在我迷路了.如何将[200,599]的数组分成x和y?apply.bind究竟是如何工作的?

function getY(x) {
        return new Promise( function(resolve,reject){
            setTimeout( function(){
                resolve( (3 * x) - 1 );
            }, 100 );
        } );
    }

function foo(bar,baz) {
    var x = bar * baz;

    // return both promises
    return [
        Promise.resolve( x ),
        getY( x )
    ];
}

function spread(fn) {
    return Function.apply.bind( fn, null );
}

Promise.all(
    foo( 10, 20 )
)
.then(
    spread( function(x,y){
        console.log( x, y );    // 200 599
    } )
)
Run Code Online (Sandbox Code Playgroud)

Mad*_*iha 9

.apply()是一个关于函数对象的方法.像这样:

console.log(Math.max.apply(null, [1, 2, 3])); // 3
Run Code Online (Sandbox Code Playgroud)

.apply()接受两个参数,上下文(将成为this目标函数内部)和一个可迭代的参数(通常是一个数组,但arguments数组也可以工作).


.bind()是一个关于函数对象的方法.像这样:

const x = {
  foo: function() {
    console.log(this.x);
  },
  x: 42
}

var myFoo = x.foo.bind({x: 5});

x.foo(); // 42
myFoo(); // 5
Run Code Online (Sandbox Code Playgroud)

.bind()获取上下文(将成为什么this),以及可选的其他参数,并返回一个新函数,上下文绑定,并锁定其他参数


因为.apply()它本身就是一个函数,它可以绑定.bind(),如下所示:

Function.prototype.apply.bind(fn, null);
Run Code Online (Sandbox Code Playgroud)

这意味着this.apply()将是fn和第一个参数.apply()null.意思是它看起来像这样:

fn.apply(null, args)
Run Code Online (Sandbox Code Playgroud)

哪个会从数组中传播参数.


Ber*_*rgi 8

扩散取一个函数和结合apply方法来部分地将所述null的参数。简而言之,

spread(fn)
Run Code Online (Sandbox Code Playgroud)

转化为

args => fn.apply(null, args)
Run Code Online (Sandbox Code Playgroud)

与使用ES6扩展语法相同

args => fn(...args)
Run Code Online (Sandbox Code Playgroud)

该函数的名称来源于何处。


如果您想得到长答案,请记住bind它的作用:

method.bind(context, ...args1)
Run Code Online (Sandbox Code Playgroud)

返回一个像

(...args2) => method.call(context, ...args1, ...args2)
Run Code Online (Sandbox Code Playgroud)

在我们的示例中,methodis applycontextis fn和第一个参数是null,因此调用

Function.apply.bind( fn, null )
Run Code Online (Sandbox Code Playgroud)

将创建一个功能类似于

(...args2) => (Function.apply).call(fn, null, ...args2)
Run Code Online (Sandbox Code Playgroud)

fn.apply(…)考虑到这applyFunction.prototype两次访问都继承的方法,因此它等效于上面的调用。


Kei*_*ith 3

spread 函数只是一个实用函数,用于将数组转换为传递给函数的参数。apply 正在执行转换,bind 将其绑定到调用函数,以便“this”上下文连接到同一函数。

以更简单的形式了解传播如何运作 ->

spread(function (x,y){console.log(x,y);})([1,2])
Run Code Online (Sandbox Code Playgroud)

您将得到答案 1 2,因为 1 传递给 x,2 传递给 y。

因此,在您的示例中,您的 Promise.all 返回一组已解决的承诺。然后这些将被映射到函数(x,y)的参数。