首先来理解下bind的概念:bind()方法,用来创建一个函数的实例=(新函数),其新函数的this值会被绑定到给定bind()的第一个参数。
注意理解这个实例,将会是你理解bind的关键。你可以理解为新函数,也就是bind之后是生成一个新函数
例1:理解bind后的this指向。
var o = {color: 'blue'};
function sayColor() {alert(this.color)};
var objColor = sayColor.bind(o);
objColor(); // blue
由于关于bind后this指向的文章很多,这里就不多做说明。我的重点在第二,函数带多个参数时的bind情况。
例2:原函数多个参数情况(貌似可以理解为ES6里的赋予了默认参数的新函数)
function test(fA, sA, tA) {
console.log("**first|", fA);
console.log("**sec|", sA);
console.log("**third|", tA);
}
const Promise = require("bluebird");
//这是使用bind后,第三个参数值打印出来为“ping”了。
Promise.resolve("ping").then(test.bind(null, "zhou", "chang"))
**first| zhou
**sec| chang
**third| ping
//这是去掉bind之后的调用,第三个参数值打印出来为“undefined”了。也就是Promise没有传进去
Promise.resolve("ping").then(test("zhou", "chang"))
**first| zhou
**sec| chang
**third| undefined
解释:问题就在于bind是先创建一个新函数。原来test需要三个参数,而test.bind(null, “zhou”, “chang”)之后会创建一个新的带三个参数的新函数,但这个函数相当于是第一个,第二个都有默认参数的情况,相当于 let newTest= function test(fA="zhou", sA="chang", tA){...}
。所以这个时候Promise.resolve(“ping”).then(newTest)就可以传“ping”给第三个参数tA了。
实际使用场景
function downloadHashContainerFiles(targetBD/*: string*/, fileServerData/*: Object*/, parsedTbd/*: Object*/)/*: Promise*/ {
var hcFilesTempPath = config.swmDownloadProxy.dir;
return Promise.resolve(parsedTbd)
.then(getHashContainerBuildElements)
.tap(function(buildElements) {
logger.debug("Found hash container buildElements: " + JSON.stringify(buildElements, null, 2));
})
.each(function(fileData) {
return downloadAndSaveFile(hcFilesTempPath, fileData, fileServerData);
})
.then(findAndVerifyHashContainerFiles.bind(null, targetBD));
}
Promise.resolve(targetBD.data)
.tap(fs.writeFileAsync.bind(fs, path.join(loadersTempPath, targetBD.name)))
.then(parseXml2Json)
.tap(downloadHashContainerFiles.bind(null, targetBD.name, fileServerData))