如何访问承诺中的价值?

Posted

技术标签:

【中文标题】如何访问承诺中的价值?【英文标题】:How to access value inside promise? 【发布时间】:2017-04-01 13:08:54 【问题描述】:

我正在努力学习使用 Promise。 在这种情况下,我想制作一个网络 scraper 。我在这段代码中使用了request-promise

实际上 scraper 工作正常。我误解了如何在then() 中使用返回值。我也用谷歌搜索了它,但没有运气,仍然卡住了。这是我的代码。

    let categories = scraper.getCategories(promoUrl);
    categories.then(function (val) 
        let promoPerCategory = [];
        for (let i = 0, len = val.length; i < len; i++) 
            let json = 
                category: val[i].category,
                url: val[i].url,
                promo: []
            

            scraper.getPromoPerCategories(val[i].url)
            .then(function (allPromo) 
                for (let j = 0, lenResult = allPromo.length; j < lenResult; j++) 
                    json.promo.push(
                        imageUrl: allPromo[j].imageUrl,
                        merchantName: allPromo[j].merchantName,
                        promoTitle: allPromo[j].promoTitle,
                        validUntil: allPromo[j].validUntil,
                        promoUrl: allPromo[j].promoUrl
                    );

                    console.log(json.promo[j]);
                
                
            )
            promoPerCategory.push(json);
        

        result.send( "promoPerCategory": promoPerCategory );
    )

then() 内部函数 getPromoPerCategories 工作正常,我使用 console.log(json.promo[j]) 打印出值

但问题是我想将数组从 json.promo[j] 放入数组 promoPerCategory 以便我可以使用 result.send( "promoPerCategory": promoPerCategory ) 返回它

你能帮我做正确的方法吗?任何帮助将不胜感激。

结果现在是这样的

"promoPerCategory":   ["category":"Fashion","url":"https://","promo":[]

对象promo 是空数组

【问题讨论】:

【参考方案1】:

您的第一个问题是result.send 没有等待getPromoPerCategories 结果。为了实现这一点,result.send 需要在 getPromoPerCategories 承诺的回调中。看起来您还想在调用result.send 之前等待所有结果返回,因此您应该使用Promise.all 并等待所有getPromoPerCategories 承诺。例如:

categories.then(function (val) 
    let promoPerCategory = [],
        promoPerCategoryPromises = [];
    for (let i = 0, len = val.length; i < len; i++) 
        let json = 
            category: val[i].category,
            url: val[i].url,
            promo: []
        

        var promise = scrapper.getPromoPerCategories(val[i].url)
        .then(function (allPromo) 
            for (let j = 0, lenResult = allPromo.length; j < lenResult; j++) 
                json.promo.push(
                    imageUrl: allPromo[j].imageUrl,
                    merchantName: allPromo[j].merchantName,
                    promoTitle: allPromo[j].promoTitle,
                    validUntil: allPromo[j].validUntil,
                    promoUrl: allPromo[j].promoUrl
                );
                console.log(json.promo[j]);
            
            promoPerCategory.push(json);
        );

        promoPerCategoryPromises.push(promise);
    
    Promise.all(promoPerCategoryPromises).then(function() 
      result.send( "promoPerCategory": promoPerCategory );
    );
)

【讨论】:

【参考方案2】:
var data = [];

scrapper.getPromoPerCategories(val[i].url)
.then(function() 
  data.push('foo': 'bar');
);

result.send(data);

或者你可以在承诺链中 result.send()

.then(function() 
  var data = [];
  data.push('foo': 'bar');
  result.send(data);
);

【讨论】:

我相信在你的第一个例子中它会发送一个空数组。 result.send 将在承诺解决之前被调用。第二个例子虽然可以工作。 是的,我不知道如何解决它。亚历杭德罗的答案是完美的。先生也谢谢您的回答。

以上是关于如何访问承诺中的价值?的主要内容,如果未能解决你的问题,请参考以下文章

SCRUM的五个价值观

返回承诺链中的引用数据

nodejs 中的异步和 Q 承诺

如何使承诺因clojure中的错误而失败?

如何在 node.js 中的特定持续时间后强制解决承诺? [复制]

复杂承诺返回链中的承诺 catch() 顺序