我正在尝试从Firebase获取每个图像下载URL。似乎第一个“ this” 不同于第二个“ ”。如果我想让第二个“ this”等于第一个“ ”的值,我该怎么办?非常感谢!
getAllURL = product => {
// Get all the images from the firebase
var storage = firebase.storage();
console.log(this) // first this
const storageRef = storage.ref(`image/${product}`)
storageRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
imageRef.getDownloadURL().then(function(url) {
console.log(this) // second this is undefined
}).catch(function(error) {});
})
})
}
componentDidMount() {
axios.get('/user/product')
.then(res=>{
if(res.data.code==0) {
this.setState({data:res.data.data},function(){
for (var i = 0; i < this.state.data.length; i++){
this.getAllURL(this.state.data[i].productName)
}
})
}
})
}
答案 0 :(得分:1)
this
是Javascript中最confusing features之一。我建议您进一步研究该主题。
关于快捷方式,有很多方法可以解决。
第一个方法:首先将第一个分配给某个变量。
getAllURL = product => {
// Get all the images from the firebase
var storage = firebase.storage();
console.log(this) // first this
var firstThis = this; // some people prefered to assign "var that = this;", lol
const storageRef = storage.ref(`image/${product}`)
storageRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
imageRef.getDownloadURL().then(function(url) {
console.log(firstThis); // use the new variable to refer to the firstThis
}).catch(function(error) {});
});
});
}
第二种方法:利用javascript中的bind
函数(从功能编程的角度来看,它有点高级,而且效果更好)
getAllURL = product => {
// Get all the images from the firebase
var storage = firebase.storage();
console.log(this) // first this
const storageRef = storage.ref(`image/${product}`)
storageRef.listAll().then((function(result) {
result.items.forEach((function(imageRef) {
imageRef.getDownloadURL().then((function(url) {
console.log(this);
}).bind(this)).catch(function(error) {}); // yet another binding to propagate "this" inside
}).bind(this)); // another binding to force "this" on this yet another inline function to equal the first this (propagate it down)
}).bind(this)); // this binding will force "this" inside this inline function to equals the firstThis
}
注意:如果减少内联函数的数量,可能会减少混乱
getAllURL = product => {
// Get all the images from the firebase
var storage = firebase.storage();
console.log(this) // first this
const storageRef = storage.ref(`image/${product}`)
storageRef.listAll().then(listAllCallback.bind(this));
}
function listAllCallback(result) {
for (var i = 0; i<result.items.length; i++) {
var imageRef = result.items[i];
imageRef.getDownloadURL()
.then(downloadUrlCallback.bind(this))
.catch(function(error) {});
}
}
function downloadUrlCallback(url) {
console.log(this); // second this
}