我不了解此javascript程序的行为。我的意图是顺序获取三个编号的资源,但似乎“ i”已在闭包中捕获,并且仅使用了其最终值。
function fetch(x) {
console.log('fetching resource ' + x);
}
var prom = Promise.resolve();
for(var i=1; i<=3; i++) {
prom = prom.then(() => { fetch(i);} );
}
//prints
//fetching resource 4
//fetching resource 4
//fetching resource 4
我对js的了解还不足以解决这个问题-如何修改该程序以生成1、2和3?我需要在某个地方使用resolve()吗?
更新:有人指出,这个问题与JavaScript closure inside loops – simple practical example重复,从技术上讲是正确的,但是我认为这个问题是有价值的,因为它在Promises领域中有了新的应用。从技术上讲,上述问题确实可以正确回答此处提出的问题,因为该问题中的Promise元素实际上是与该答案无关的红色鲱鱼。但是,通过阅读此问题而不是前面提到的重复内容,可以将对Promise无关紧要的认识视为一种洞察力。
答案 0 :(得分:2)
将import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import reactImage from '../images/djangoreact.png'
const styles = {
card: {
width: "100%",
backgroundColor: 'black',
textAlign: 'center',
justifyContent: 'center',
alignContent: 'center',
padding: '30px'
},
media: {
height: 325,
// textAlign: 'center',
// justifyContent: 'center',
// alignContent: 'center',
},
font: {
color: 'white',
// textAlign: 'center',
// justifyContent: 'center',
// alignContent: 'center',
},
header:{
textAlign: 'center',
justify: 'center',
alignContent: 'center',
width: '100%'
}
};
function MediaCard(props) {
const { classes } = props;
return (
<div className={classes.header} style={{
justify: 'center',
alignContent: 'center',
alignItems: 'center'
}}>
<Card className={classes.card} style={{
justify: 'center',
alignContent: 'center',
alignItems: 'center'
}}>
<CardActionArea>
<CardMedia
className={classes.media}
image={reactImage}
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2" className={classes.font}>
Welcome to the KB
</Typography>
<Typography component="p" className={classes.font}>
Check out the tutorial for the Djanog/React boilerplate used to make this site!
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
</div>
);
}
MediaCard.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(MediaCard);
更改为var
let
或为同一个人创建IIFE
function fetch(x) {
console.log('fetching resource ' + x);
}
var prom = Promise.resolve();
for(let i=1; i<=3; i++) {
prom = prom.then(() => { fetch(i);} );
}
答案 1 :(得分:0)
创建一个const
来存储所需的值。
function fetch(x) {
console.log('fetching resource ' + x);
}
var prom = Promise.resolve();
for(var i=1; i<=3; i++) {
const j = i;
prom = prom.then(() => { fetch(j);} );
}
答案 2 :(得分:0)
将您的每个内容都包装为闭包以保持i的值;
function fetch(x) {
console.log('fetching resource ' + x);
}
for(var i=1; i<=3; i++) {
(function(index){Promise.resolve().then(() => { fetch(index);} )})(i);
}
答案 3 :(得分:0)
我建议您将promise放入for循环中,如下所示:
function fetch(x) {
console.log('fetching resource ' + x);
}
for(var i=1; i<=3; i++) {
var prom = Promise.resolve(i);
prom.then(fetch);
}
或者,如果您想在循环之外定义promise,则可以创建一个临时数组以使用Promise.all
function fetch(x) {
console.log('fetching resource ' + x);
}
var arr = [];
for(var i=1; i<=3; i++) {
arr.push(i);
}
Promise.all(arr).then(values =>
{
values.forEach(fetch);
});
答案 4 :(得分:0)
这里的问题几乎与Promise无关,与与闭包无关。您的代码:
for(var i=1; i<=3; i++) {
prom = prom.then(() => { fetch(i);} );
}
表示“当诺言解决后,调用该匿名函数,该函数以{strong> current 值为fetch()
来调用i
。”当前值。由于此时您已经退出了for循环(因为确保从该代码返回之前不会调用匿名函数),所以i
等于4。
Ricky Mo提供了一种实用的方法来做您显然想做的事情。