我很难理解如何在Promises中做到这一点,因为我今天开始了解它们。我想做的是:
这是我到目前为止所做的事情:
以下函数遍历所有页面。
function getAllCountries(requestURL, pageNr, countries) {
return Request({
'method': 'GET',
'uri': requestURL,
'json': true,
}).then((response) => {
if (!countries) {
countries = [];
}
countries = countries.concat(response.data);
const meta = response.meta;
if (pageNr < meta['pagination']['total_pages']) {
pageNr += 1;
let formattedLink = Format(BASE_URL, API_TOKEN, pageNr);
return getAllCountries(formattedLink, pageNr, countries);
}
return countries;
});
}
这是我遇到麻烦的地方:
getAllCountries(formattedLink, pageNr)
.then((countries) => {
// will call handleCountry method for each country here
// how do I handle the callback to/from handleCountry here?
// that is wrong
// countries.map(handleCountry);
})
.then(() => {
console.log('Handled all countries');
return res.sendStatus(200);
})
.catch((error) => {
console.log(error);
return res.sendStatus(500);
});
以下是handleCountry函数的用法:
function handleCountry(country, callback) {
// do stuff here
if (!country["extra"]) {
app.models.Country.upsert(countryJson, callback);
} else {
// do async stuff here, image upload etc with Async.auto
Async.auto({
'uploadImage': (autoCallback) => {
uploadImage(autoCallback);
}
'updateOnDb': ['uploadImage', (results, autoCallback) => {
// do stuff
app.models.Country.upsert(countryJson, autoCallback);
}
}, callback);
}
}
我该怎么办?顺便说一句,处理国家的顺序并不重要。
答案 0 :(得分:0)
function getAllCountries(requestURL, pageNr, countries) {
Request({
'method': 'GET',
'uri': requestURL,
'json': true,
}).then((response) => {
if (!countries) {
countries = [];
}
countries = countries.concat(response.data);
const meta = response.meta;
if (pageNr < meta['pagination']['total_pages']) {
pageNr += 1;
let formattedLink = Format(BASE_URL, API_TOKEN, pageNr);
// declaring array to be passed inside promise.all
let countriesPromises = [];
// creating promises for each country
countries.forEach(function(country) {
countriesPromises.push(new Promise(function(){
handleCountry(country,callback);
})
});
}
// callback for all countries.
Promise.all(countriesPromises)
.then(() => {
console.log('Handled all countries');
return res.sendStatus(200);
})
.catch((error) => {
console.log(error);
return res.sendStatus(500);
})
}
}
在获得所有国家之后,我们为每个国家创建了承诺,并在数组中最终将它们传递给promise.all(),这允许我们绑定回调以完成所有承诺。请注意,我已经删除了所有return语句并且getAllCountries不再可用,我们已经在getAllCountries本身内部实现了回调。您可以根据自己的需要将其分开。
答案 1 :(得分:0)
问题是handleCountryAsync()
没有玩#34;承诺游戏&#34; - 它接受回调而不是返回承诺。
您可以通过重写handleCountry()
进行宣传,但保持handleCountry()
完好无损并编写适配器handleCountryAsync()
如下:
function handleCountryAsync(country) {
return new Promise((resolve, reject) => {
try {
handleCountry(country, (...args) => {
resolve(args); // promises can be fulfilled only with a single value, but multiple arguments can be delivered as an array.
});
}
catch(error) {
reject(error);
}
});
}
现在,更高级别代码中的公开回调需求消失,countries.map()
可以向Promise.all()
返回一系列承诺:
getAllCountries(formattedLink, pageNr)
.then(countries => Promise.all(countries.map(handleCountryAsync)))
.then(() => {
console.log('Handled all countries');
return res.sendStatus(200);
})
.catch((error) => {
console.log(error);
return res.sendStatus(500);
});
这就是它的本质。其他考虑因素主要围绕错误处理。例如,您有一个设计决策 - 是否吞下错误或允许handleCountryAsync
单个失败产生500.如上所述,它是后者。