将嵌套 AJAX 调用转换为顺序 Promise
Convert nested AJAX call to sequential Promises
我的代码成功地 运行ning AJAX 按顺序调用(对我的员工进行粗略的互联网延迟测试):
const start = new Date().getTime();
const testUrl = "our server URL";
const start = new Date().getTime();
$.ajax(testUrl + '?delay=0.0&length=100').done(function(){
$.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
$.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
$.ajax(testUrl + '?delay=0.1&length=100000').done(function(){
$.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
$.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
$.ajax(testUrl + '?delay=0.0&length=100').done(function(){
$.ajax(testUrl + '?delay=0.1&length=10').done(function(){
const end = new Date().getTime();
internetTestTime = end - start;
console.log('Your internet test time: ' + internetTestTime + 'ms')
})
})
})
})
})
})
})
});
我想将其切换为按顺序使用 运行 的 Promise。这是目前的进展:
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
let testSequence = Promise.resolve();
testSuiteInputs.forEach(testSuiteInput => {
// something goes here...
});
testSequence.then(() => {
const end = new Date().getTime();
internetTestTime = end - start;
console.log('Your internet test time: ' + internetTestTime + 'ms')
});
我需要在上面填写什么才能按顺序做出这些承诺运行?
嗯,最简单的方法是将 .forEach()
循环切换为 async
函数内的普通 for
循环,然后使用 await
:
async function run() {
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
for (let item of testSuiteInputs) {
let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
let result = await $.ajax(url);
// process result here
}
}
run().then(finalResult => {
console.log("all done");
}).catch(err => {
console.log(err);
});
要在不使用 async/await
的情况下执行此操作,对数组进行异步访问排序的常见设计模式是使用 .reduce()
,您只需将承诺链接在一起:
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
testSuiteInputs.reduce((p, item) => {
return p.then(() => {
// when previous ajax call finished, start the next one
let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
return $.ajax(url).then(result => {
// process individual result here
});
});
}, Promise.resolve()).then(finalResult => {
console.log("all done");
}).catch(err => {
console.log(err);
});;
我的代码成功地 运行ning AJAX 按顺序调用(对我的员工进行粗略的互联网延迟测试):
const start = new Date().getTime();
const testUrl = "our server URL";
const start = new Date().getTime();
$.ajax(testUrl + '?delay=0.0&length=100').done(function(){
$.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
$.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
$.ajax(testUrl + '?delay=0.1&length=100000').done(function(){
$.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
$.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
$.ajax(testUrl + '?delay=0.0&length=100').done(function(){
$.ajax(testUrl + '?delay=0.1&length=10').done(function(){
const end = new Date().getTime();
internetTestTime = end - start;
console.log('Your internet test time: ' + internetTestTime + 'ms')
})
})
})
})
})
})
})
});
我想将其切换为按顺序使用 运行 的 Promise。这是目前的进展:
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
let testSequence = Promise.resolve();
testSuiteInputs.forEach(testSuiteInput => {
// something goes here...
});
testSequence.then(() => {
const end = new Date().getTime();
internetTestTime = end - start;
console.log('Your internet test time: ' + internetTestTime + 'ms')
});
我需要在上面填写什么才能按顺序做出这些承诺运行?
嗯,最简单的方法是将 .forEach()
循环切换为 async
函数内的普通 for
循环,然后使用 await
:
async function run() {
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
for (let item of testSuiteInputs) {
let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
let result = await $.ajax(url);
// process result here
}
}
run().then(finalResult => {
console.log("all done");
}).catch(err => {
console.log(err);
});
要在不使用 async/await
的情况下执行此操作,对数组进行异步访问排序的常见设计模式是使用 .reduce()
,您只需将承诺链接在一起:
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
testSuiteInputs.reduce((p, item) => {
return p.then(() => {
// when previous ajax call finished, start the next one
let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
return $.ajax(url).then(result => {
// process individual result here
});
});
}, Promise.resolve()).then(finalResult => {
console.log("all done");
}).catch(err => {
console.log(err);
});;