【问题标题】:I am trying to use promise ina function to receive data and put them in array and then return the array我正在尝试在函数中使用 promise 来接收数据并将它们放入数组中,然后返回数组
【发布时间】:2018-02-03 00:20:59
【问题描述】:

我的函数使用了 Promise,但它不能正常工作:

getShirtcolorsCount(){
    var params_red ;
    var red ;
    var params_blue ;
    var blue ;
    var numb = 0 ;
    var docClient = new DynamoDB.DocumentClient();

    // Query voor Shirts 
    params_red = {
        TableName: 'ShirtApp',
        IndexName: 'Shirt-index',
        KeyConditionExpression: 'ShirtC = :sbs AND ShirtQuantity >  :snr ' ,
        ExpressionAttributeValues: {
            ':sbs': 'Red' ,
            ':snr' : numb
        }
    };

    var redPromise = docClient.query(params_red).promise();
    redPromise.then(function(data){
        console.log('Success');  
        red = data.Count;
    }).catch(function(err) {
        console.log(err);
    });

    params_blue = {
        TableName: 'ShirtApp',
        IndexName: 'Shirt-index',
        KeyConditionExpression: 'ShirtC = :sbs AND ShirtQuantity >  :snr ' ,
        ExpressionAttributeValues: {
            ':sbs': 'Blue' ,
            ':snr' : numb
        }
    };

    var bluePromise = docClient.query(params_blue).promise();
    bluePromise.then(function(data){
        console.log('Success');  
        blue = data.Count ;      //NEED THAT to add to the array
    }).catch(function(err) {
        console.log(err);
    });

    var ShirtInfo = [{
        name: 'RedColor',
        value: red
    }, {
        name: 'BlueColor',
        value: blue
    }];

    // **** HERE I NEED HELP what should I PUT in the Promise.all for the array
    // I want redPromise and bluePromise to run at the same time after I receive 
    // data then add then to the array and return the array as the function
    Promise.all([redPromise, bluePromise]).then([ShirtInfo])

    return ShirtInfo;
}

正如我在 cmets 中添加的那样,我想同时运行 redPromiseBluePromise,并在它们从网络接收到数据后,将它们添加到数组中。之后返回该数组。几乎所有东西都只适用于使用Promise.all 的部分。我不知道在.then 后面放什么,所以这些值将被添加到数组中:

Promise.all([redPromise, bluePromise]).then([])

而且我无法弄清楚使用 promise 返回数组的内容。

【问题讨论】:

  • 您需要访问redPromisebluePromisePromise.all#then 中的resolve 值吗?
  • 格式错误的代码

标签: javascript angular promise amazon-dynamodb aws-sdk-js


【解决方案1】:

一些问题:

  • 您需要在then 回调中返回redblue 的值,否则这些承诺将解析为undefined
  • 同样需要返回Promise.all的返回值
  • 您不能同时访问redblue,因为它们仍然是未定义的。所以这必须在 then 回调中发生。

我也会避免您的代码重复,并使用您感兴趣的颜色列表,然后循环浏览这些颜色:

getShirtcolorsCount(){
    var params;
    var colors;
    var promises;
    var numb = 0;
    var docClient = new DynamoDB.DocumentClient();

    colors = ['Red', 'Blue']; // <--- make code generic
    promises = colors.map(function (color) {
        // Query voor Shirts 
        var param = {
            TableName: 'ShirtApp',
            IndexName: 'Shirt-index',
            KeyConditionExpression: 'ShirtC = :sbs AND ShirtQuantity > :snr ',
            ExpressionAttributeValues: {
                ':sbs': color, // <-- make it dynamic to avoid code duplication
                ':snr' : numb
            }
        };
        return docClient.query(params_red).promise();
    });

    // Make sure to return the promise    
    return Promise.all(promises).then(function (responses) {
        console.log('Success');  
        var shirtInfo = responses.map(function (data, i) {
            return {
                name: color[i] + 'Color',
                value: data.Count
            };
        });
        return shirtInfo;
    }).catch(function(err) {
        console.log(err);
    });
}

使用 Promise 后,您也必须将结果用作 Promise。您不能期望函数同步返回值。所以当你调用getShirtcolorsCount时,使用then来访问结果:

getShirtcolorsCount().then(function (shirtInfo) {
    console.log(shirtInfo);
});

【讨论】:

  • 这部分代码值出现错误:data.Count 错误为 [ts] 类型“{}”上不存在属性“Count”。任何。如果我删除 .Count 它可以工作,但我不需要所有整个对象只需要 Count 属性
  • 我收到错误但已修复它 return Promise.all(promises).then(function (responses) { } 需要 ---> (responses: any)
  • 好的,这是一个 TypeScript 错误。我的答案是纯 JavaScript。但确实使用: any,您可以规避 TypeScript 的抱怨。
  • 因为我在 Angular 中使用它,所以我需要将 shirtInfo 的返回添加到组件中的 var tingle,所以我这样做了,它起作用了 this.ddb.getShirtcolorsCount().then(shirtInfo => this.tingle = shirtInfo);我再次感谢您的帮助
【解决方案2】:

你的案例结果来自 redPromisebluePromise 写在函数范围变量中,可以像这样推送到数组:

return new Promise(function (resolve, reject) {
  Promise.all([redPromise, bluePromise]).then(function () {
    ShirtInfo.push(red)
    ShirtInfo.push(blue)
    resolve(ShirtInfo)
  })
}

在你调用获取这个数组的函数的地方你也应该使用

getShirtColorsCount().then(function(shirtInfo) {
  // Stuff
})

附言它会回调地狱。可能更好地使用babelasync-await 或生成器函数?它会更具可读性

【讨论】:

  • 您不应提供使用Promise constructor anti-pattern的代码。
  • @trincot 我不知道。我一直用这个
  • @trincot 也 eslint:standard not mark that as antipattern
猜你喜欢
  • 2022-11-15
  • 2020-08-14
  • 2015-07-26
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多