我需要按顺序发送请求,但在返回错误时停止序列,我正在使用 Angular $http提供程序。
我的代码是这样的:
const steps = [
{ url: '/api/test/1' },
{ url: '/api/test/2' },
{ url: '/api/test/3' },
{ url: '/api/test/4' },
]
const executeStep = index => {
// Validate step existence
if (typeof steps[index] == 'undefined') return
// Request
$http({method: 'get', url: steps[index].url})
.success(response => {
if (!response.success) throw response
executeStep(index+1)
}).error(err => {
console.error(err)
alert('Error')
})
}
executeStep(0)
我的问题是:有更好的方法来完成这项工作吗?
这是代码,与您的代码非常相似,但没有处理或添加索引号,因此更清晰一些。
const queue = [
{ url: '/api/test/1' },
{ url: '/api/test/2' },
{ url: '/api/test/3' },
{ url: '/api/test/4' },
];
function runQueue() {
const req = queue[0];
$http({method: 'get', url: req.url})
.success(response => {
console.log(response);
queue.shift();
if (queue.length > 0) {
runQueue();
}
})
.error(err => {
console.error(err);
})
}
使用蓝鸟承诺的解决方案。
另一个不错的选择是(特别是如果你的代码是服务器端nodejs)使用bluebird Promise库。该库现在不是很受欢迎,因为几乎在任何地方都支持承诺。但是仍然有一些方法非常有用。在您的情况下,Promise.每种方法都将完美运行。
const Promise = require('bluebird'); // or import * as Promise from 'bluebird';
const queue = [
{ url: '/api/test/1' },
{ url: '/api/test/2' },
{ url: '/api/test/3' },
{ url: '/api/test/4' },
];
Promise.each(queue, (req) => {
return http$({method: 'get', url: req.url}).then((resp) => {
console.log(resp);
});
}).then(() => {
console.log("done");
}).catch(err => {
console.error(err);
})
你需要的是promise链接和递归。
const steps = [
{ url: '/api/test/1' },
{ url: '/api/test/2' },
{ url: '/api/test/3' },
{ url: '/api/test/4' },
]
const executeStep = index => {
// Validate step existence
if (typeof steps[index] == 'undefined') return true;
// Request
return $http({method: 'get', url: steps[index].url})
.then(response => {
if (!response.success) throw response
return executeStep(index+1)
})
}
executeStep(0)
.then( () => console.log('all done'))
.catch(e => console.error('something failed', e))
在这里,每次请求完成时,它都会返回一个包含下一个请求的新承诺。这样executeStep(0)
只有在所有其他承诺都完成时才会解决,或者如果任何承诺遇到错误,它将立即被拒绝。
您可以将异步函数与承诺结合使用。
const queue = [
{ url: '/api/test/1' },
{ url: '/api/test/2' },
{ url: '/api/test/3' },
{ url: '/api/test/4' },
];
function oneRequest(req) {
return new Promise((resolve,reject)=>{
$http({method: 'get', url: req.url})
.success(response => resolve(response))
.error(err => reject(err));
});
}
async function allRequests(reqs) {
let resps = [];
for(var i=0;i<reqs.length;i++) {
let resp = await oneRequest(reqs[i]);
resps.push(resp);
}
return resps;
}
allRequests(queue)
.then(resps => console.log(resps))
.catch(err => console.log(err));