如何将价值传递给javascript Promise

时间:2018-11-07 03:39:21

标签: javascript es6-promise

我不了解此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无关紧要的认识视为一种洞察力。

5 个答案:

答案 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提供了一种实用的方法来做您显然想做的事情。

相关问题