此刻,我正在使用下面的代码使用异步等待来获取多个Promises的结果:
let matchday = await createMatchday(2018, 21, [/*9 matches of matchday*/]);
//Further calculations
async function createMatchday(seasonNr, matchdayNr, matches) {
let md = new Matchday(seasonNr, matchdayNr, matches);
await md.getStandings(seasonNr, matchdayNr);
return md;
}
class Matchday {
constructor(seasonNr, matchdayNr, matches) {
this.seasonNr = seasonNr;
this.matchdayNr = matchdayNr;
this.matches = matches;
}
async getStandings(seasonNr, matchdayNr) {
let promiseArr = [];
promiseArr.push(makeHttpRequestTo(`http://externService.com/standings?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`);
promiseArr.push(makeHttpRequestTo(`http://externService.com/homestandings?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`));
promiseArr.push(makeHttpRequestTo(`http://externService.com/awaystandings?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`));
promiseArr.push(makeHttpRequestTo(`http://externService.com/formstandings?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`));
let resulArr = await Promise.all(promiseArr);
this.standings = resultArr[0];
this.homeStandings = resultArr[1];
this.awayStandings = resultArr[2];
this.formStandings = resultArr[3];
}
}
function makeHttpRequest(url) {
return new Promise((resolve, reject) => {
//AJAX httpRequest to url
resolve(httpRequest.responseText);
}
}
这实际上是读取多个promise的值的最佳方法,其中promise.all()不需要彼此等待,而是可以同时工作,或者是否有更好的方法使同时出现几个httpRequest,因为这看起来很重复吗?
答案 0 :(得分:2)
您的所有URL都遵循相同的模式,因此您可以通过map
对URL ['', 'home', 'away', 'form']
的数组解析来极大地减少代码。然后,通过map
makeHttpRequestTo
到Promises的URL,然后可以将等待的结果分解为this.
属性:
async getStandings(seasonNr, matchdayNr) {
const urls = ['', 'home', 'away', 'form']
.map(str => `http://externService.com/${str}standings?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`);
const promiseArr = urls.map(makeHttpRequestTo);
[
this.standings,
this.homeStandings,
this.awayStandings,
this.formStandings
] = await Promise.all(promiseArr);
}
要分别填充每个属性,而不是等待所有响应返回:
async getStandings(seasonNr, matchdayNr) {
['', 'home', 'away', 'form']
.forEach((str) => {
const url = `http://externService.com/${str}standings?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`;
makeHttpRequestTo(url)
.then((resp) => {
this[str + 'Standings'] = resp;
});
});
}
答案 1 :(得分:0)
要回答,不,您不应阻止彼此不依赖的其他XHR或任何I / O请求。我会这样写你的函数的;
const getFavourites = async () => {
try {
const result = await Promise.resolve("Pizza");
console.log("Favourite food: " + result);
} catch (error) {
console.log('error getting food');
}
try {
const result = await Promise.resolve("Monkey");
console.log("Favourite animal: " + result);
} catch (error) {
console.log('error getting animal');
}
try {
const result = await Promise.resolve("Green");
console.log("Favourite color: " + result);
} catch (error) {
console.log('error getting color');
}
try {
const result = await Promise.resolve("Water");
console.log("Favourite liquid: " + result);
} catch (error) {
console.log('error getting liquid');
}
}
getFavourites();
这样,每个异步函数都会被立即调用,并且没有异步动作会阻止其他动作。
答案 2 :(得分:0)
如果您不希望在继续执行流程之前等待所有请求完成,则可以使该类的属性成为承诺:
class Matchday {
constructor(seasonNr, matchdayNr, matches) {
this.seasonNr = seasonNr;
this.matchdayNr = matchdayNr;
this.matches = matches;
['standings', 'homeStandings', 'awayStandings', 'formStandings'].forEach(propertyName => {
let url = `http://externService.com/${propertyName.toLowerCase()}`
+ `?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`
this[propertyName] = makeHttpRequestTo(url)
});
}
}
class Matchday {
constructor(seasonNr, matchdayNr, matches) {
this.seasonNr = seasonNr;
this.matchdayNr = matchdayNr;
this.matches = matches;
['standings', 'homeStandings', 'awayStandings', 'formStandings'].forEach(propertyName => {
let url = `http://externService.com/${propertyName.toLowerCase()}`
+ `?seasonNr=${seasonNr}&matchdayNr=${matchdayNr}`
this[propertyName] = makeHttpRequestTo(url)
});
}
}
/**************************************
* Test harness
**************************************/
function makeHttpRequestTo(url) {
// Fake an AJAX httpRequest to url
const requested_resource = url.match('^.*\/\/.*\/([^?]*)')[1];
const fake_response_data = 'data for ' + url.match('^.*\/\/.*\/(.*)$')[1];
let delay = 0;
let response = '';
switch (requested_resource) {
// To make it interesting, let's give the 'standings' resource
// a much faster response time
case 'standings':
delay = 250;
break;
case 'homestandings':
delay = 2000;
break;
case 'awaystandings':
delay = 3000;
break;
case 'formstandings':
delay = 4000; // <== Longest request is 4 seconds
break;
default:
throw (util.format('Unexpected requested_resource: %s', requested_resource));
}
return new Promise((resolve, reject) => {
setTimeout(() => resolve(fake_response_data), delay);
});
}
async function testAccessingAllProperties() {
const testId = "Test accessing all properties";
console.log('\n%s', testId);
console.time(testId)
let md = new Matchday(2018, 21, []);
console.log(await md.standings);
console.log(await md.homeStandings);
console.log(await md.awayStandings);
console.log(await md.formStandings);
console.timeEnd(testId)
}
async function testAccessingOnlyOneProperty() {
const testId = `Test accessing only one property`;
console.log('\n%s', testId);
console.time(testId)
let md = new Matchday(2018, 21, []);
console.log(await md.standings);
console.timeEnd(testId)
}
async function all_tests() {
await testAccessingAllProperties();
await testAccessingOnlyOneProperty();
}
all_tests();
上面的代码片段显示执行时间不受未访问的属性的影响。而且访问所有属性的执行时间并不比使用promise.all
差。
访问这些属性时,您只需要记住使用await
。
答案 3 :(得分:-1)
要创建Promise,您需要调用新的Promise((resolve,reject)=> {return“ Pizza”;})
您做对了
如果您愿意,可以使用数组(及其函数,如map
等来缩短代码,但不会提高其性能