admin管理员组文章数量:1186688
So I get that an array of [200,599] is returned from the promise and the callback function inside spread is being passed into Function.apply.bind, but now I'm lost. How is the array of [200,599] split into x and y? How exactly does the apply.bind work?
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
} )
)
So I get that an array of [200,599] is returned from the promise and the callback function inside spread is being passed into Function.apply.bind, but now I'm lost. How is the array of [200,599] split into x and y? How exactly does the apply.bind work?
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
} )
)
Share
Improve this question
asked Oct 6, 2016 at 22:59
Gwater17Gwater17
2,3143 gold badges23 silver badges45 bronze badges
1
- You know what they do on their own, right? – Bergi Commented Oct 6, 2016 at 23:24
4 Answers
Reset to default 14.apply()
is a method on function objects. Like so:
console.log(Math.max.apply(null, [1, 2, 3])); // 3
.apply()
accepts two arguments, the context (what would become this
inside of the target function) and an iterable of arguments (usually an array, but the arguments
array like also works).
.bind()
is a method on function objects. Like so:
const x = {
foo: function() {
console.log(this.x);
},
x: 42
}
var myFoo = x.foo.bind({x: 5});
x.foo(); // 42
myFoo(); // 5
.bind()
takes a context (what would become this
), and optionally, additional arguments, and returns a new function, with the context bound, and the additional arguments locked
Since .apply()
is a function in on itself, it can be bound with .bind()
, like so:
Function.prototype.apply.bind(fn, null);
Meaning that the this
of .apply()
would be fn
and the first argument to .apply()
would be null
. Meaning that it would look like this:
fn.apply(null, args)
Which would spread the parameters from an array.
Spread takes a function and binds the apply
method to, partially applying the null
argument. So in short,
spread(fn)
is transformed to
args => fn.apply(null, args)
which is the same as using the ES6 spread syntax
args => fn(...args)
where the function got its name from.
If you want the long answer, remember what bind
does:
method.bind(context, ...args1)
returns a function that works like
(...args2) => method.call(context, ...args1, ...args2)
In our case, method
is apply
, the context
is fn
and the first arguments are null
, so the call
Function.apply.bind( fn, null )
will create a function that works like
(...args2) => (Function.apply).call(fn, null, ...args2)
which is equivalent to the fn.apply(…)
call above, given that apply
is the method inherited from Function.prototype
in both accesses.
The spread function is just a utility function to convert an array, into parameters passed to a function. The apply is doing the converting, and the bind is binding it to the calling function so that the "this" context is connected to same function.
To see how spread is working in a simpler form ->
spread(function (x,y){console.log(x,y);})([1,2])
You will get the answer, 1 2, as 1 is passed to x, and 2 is passed to y.
So in your example your promise.all is returning an array of resolved promises. These are then getting mapped to parameters to your function(x,y).
The reason it works is the "destructuring" nature of apply
(if given an array of values, they would be provided spreaded to the function you use apply on).
Now back to your code when calling bind on apply, the value returned is a function which returns the same function provided to bind
, the only thing different is when executed it would be called using apply
(with an array as thisArg in your case), but it isn't going to be executed until you call it.
In your case when the promise has resolved, the function provided tothen
woule be executed with an array of arguments provided by Promise
resolution.
function spread(fn){
let boundedFn = fn.bind(fn)
return function(arg){
return boundedFn.apply(null,arg)
}
}
spread((x, y, c) => console.log(x, y, c))([1,2,3])
// or
Promise.resolve([6, 5]).then(spread((a, b) => console.log(a, b)))
The reason bind
is provided (in your code) with null
as second param is to prevent the array provided by the caller from being given to apply
as its first param, which reserved for this
.
本文标签: javascriptHow does functionapplybind work in the following codeStack Overflow
版权声明:本文标题:javascript - How does function.apply.bind work in the following code? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738362899a2081066.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论