我认为我正在寻找承诺,但我不知道如何在我的案例中使用它。
我只想在完成所有异步代码时console.log('ended')
。我有一个DZ.api的回调但不是forEach()
的回调,这样做的最佳方式是什么? / p>
_.forEach(filteredTracks, function(n) {
DZ.api('/playlist/'+ n.id +'/tracks', function(response) {
_.forEach(response.data, function(n) {
SP.api('/search/'+n.title, function(response) {
console.log(response);
});
});
});
});
console.log('ended');
答案 0 :(得分:4)
您正在寻找Promise.all - > Promise.all(arrayOfPromise).then(function (result) {})
使用您当前的代码,如果SP.api已经与Promise兼容,请执行以下操作:
_.map(filteredTracks, function(n) {
return DZ.api('/playlist/'+ n.id +'/tracks')
.then(function (response) {
_.map(response.data, function(n) {
return SP.api('/search/'+n.title);
});
return Promises.all(response.data);
});
});
});
Promise.all(filteredTracks)
.then(function (results) {
console.log('ended');
});
如果SP.api和DZ Api未返回承诺,您可以:
Promisify SP.api DZ Api并使用我之前编写的相同代码
或者在._map
中返回promises_.map(filteredTracks, function(n) {
var promise = new Promise(function (resolve, reject) {
DZ.api('/playlist/'+ n.id +'/tracks', function (response) {
_.map(response.data, function(n) {
var insidePromise = new Promise(function (resolve, reject) {
return SP.api('/search/'+n.title, function (result) {
resolve(result);
});
})
return insidePromise;
});
resolve(Promises.all(response.data));
});
});
});
return promise;
});
Promise.all(filteredTracks).then(function (results) {
console.log('ended');
});
答案 1 :(得分:2)
你想要的是用forEach
替换map
并让每个调用返回一个Promise,连接内循环的结果,因为你有两个级别。然后将Promises数组传递给Promise.all()
,这会创建一个Promise,当数组中的所有Promise都已解析时,它会解析。为此,您必须重构代码以从DZ.api
函数返回Promises而不是使用回调。简而言之:
let promises = filteredTracks.map(track => {
return DZ.promisedApi(track).then(response => {
return Promise.all(response.data.map(n => SP.promisedApi(n))
})
})
Promise.all(promises).then(() => console.log("done!"))
答案 2 :(得分:1)
您没有指定您正在使用的库,但总体而言我建议您将所有API调用的承诺保存到数组中,然后使用Promises.all()
所以你会有类似的东西(警告:未经测试的代码,仅供参考):
var promisesArray = []
_.forEach(filteredTracks, function(n) {
DZ.api('/playlist/'+ n.id +'/tracks', function(response) {
_.forEach(response.data, function(n) {
promisesArray.push( SP.api('/search/'+n.title, function(response) {
console.log(response);
}));
});
});
});
Promise.all(promisesArray)
.then(function(value){
console.log('ended');
})
基本上,正如Promise reference page所述,Promise.all创建了一个新的Promise,当所有作为参数传递的promise被解析时,它将被解析。在我看来,这与您的用例相符。