gpt4 book ai didi

javascript - 异步函数在调用一次时有效,但多次调用时无效

转载 作者:行者123 更新时间:2023-12-03 12:43:25 27 4
gpt4 key购买 nike

我已经使用 async.waterfall 来展平嵌套函数,如下所示。

function convertPortfolio(trademarks, fn){
async.waterfall([function(callback){
groupByCountry(trademarks, callback)
},
function(TMsGroupedByCountry, callback){
addEUTrademarks(TMsGroupedByCountry['EU'], TMsGroupedByCountry, callback)
},
function(revisedGroupByCountry, callback){
groupTrademarksByStatus(revisedGroupByCountry, callback)

}], function(err, splitByStatus){
fn(null, splitByStatus);
})
}

嵌套替代

function convertPortfolio(trademarks, fn){
groupByCountry(trademarks, function(err, TMsGroupedByCountry){
addEUTrademarks(TMsGroupedByCountry['EU'], TMsGroupedByCountry, function(err, revisedGroupByCountry){
groupTrademarksByStatus(revisedGroupByCountry, function(err, splitByStatus){
fn(null, splitByStatus)
});
});
});
}

随后,当我将这个函数作为另一个函数的一部分调用一次时,它工作得很好。但是,当我尝试使用数组上的 forEach 调用中的单独值多次调用该函数时,当嵌套版本工作正常时,它无法工作。我无法解释为什么会出现这种情况,老实说,我不知道从哪里开始。我的理解是 forEach 调用应该简单地意味着每个单独的值都被相应地处理并关闭,所以这不应该是问题。

异步函数在此实例中正常工作并返回值

exports.convertPortfolioAndAddToGeoJSON = function(geojson, trademarks, fn){
convertPortfolio(trademarks, function(err, revisedTMs){
addToGeoJson(geojson, revisedTMs, function(err, gj){
fn(null, gj)
});
});
}

但在本例中,最终目标对象未填充:

exports.convertYearPortfolioAndAddToGeoJSON = function(geojson, trademarks, fn){
var target = {};
Object.keys(trademarks).forEach(function(year){
convertPortfolio(trademarks[year], function(err, revisedTMs){
addToGeoJson(geojson, revisedTMs, function(err, revisedGeoJSON){
target[year] = revisedGeoJSON;
});
});
});
fn(null, target);
}

在某些点使用 console.log 表明,在嵌套示例中,返回值在记录目标对象之前被记录,而对于 async.waterfall 示例,目标对象在返回数据可用之前被记录(所以我认为记录目标结果为空对象并不奇怪)。

我认为在每种情况下,回调的存在意味着目标的日志记录只会在所有先前处理完成后才会发生,但尽管嵌套替代方案似乎是这种情况,但事实并非如此至少在多次调用时使用异步版本。

任何指导将不胜感激。

更新出于兴趣,这里是使用 async.forEach 的修改后的代码:

exports.convertYearPortfolioAndAddToGeoJSON = function(geojson, trademarks, fn){
var target = {};
async.forEach(Object.keys(trademarks), function(year, callback){
async.waterfall([
async.apply(convertPortfolio, trademarks[year]),
function(revisedTMs, callback){
addToGeoJson(geojson, revisedTMs, callback)
}],
function(err, revisedGeoJSON){
target[year] = revisedGeoJSON;
callback()
})
}, function(err){
fn(null, target);
});
}

最佳答案

Object.keys(trademarks).forEach 是同步的,无法正确跟踪闭包/范围。您需要在那里使用 async.forEach(Object.keys(trademarks), function(year, callback).... ,并相应地调整异步控制流。

也仅供引用,当你有这个带有微小包装函数的模式时:

function convertPortfolio(trademarks, fn){
async.waterfall([function(callback){
groupByCountry(trademarks, callback)
},

您可以为该样板使用async.apply:

function convertPortfolio(trademarks, fn){
async.waterfall([async.apply(groupByCountry, trademarks),
...

关于javascript - 异步函数在调用一次时有效,但多次调用时无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23442749/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com