Angular 4 中的 Observable 调用可以像 jquery 的同步 ajax 方式吗?
Can the Observable call in Angular 4 be like jquery's sync ajax way?
我有一些业务逻辑函数要调用,它有一个必须使用 HttpGet 的逻辑,如果我使用 jquery,我必须等到它 returns 结果才能继续ajax可以简单搞定,不知道Observable是否也有类似的做法?
我希望结果是:
- 约翰
- 安迪
但现在结果只显示 Andy :(
function main(){
/*
I have more than 70 sharing rules to deal with different Logic
(e.g. getAge , getSomthing...), in order to simplify the problem ,
I only list two rules as a demonstration
*/
methods = [
getNameFromServer,
getSomeOneName
];
const result = [];
methods.forEach(method => {
method(result);
})
console.log(result);
}
function getNameFromServer(result){
Rx.Observable.of('John')
.delay(1000)
.subscribe(name => {
console.log('now async get name , but I need it will be sync')
result.push(name)
});
// can I use sync Ajax like jquery's code?
// $.ajax({
// ... ,
// async: false
// })
// .done(response => result.push(response.xxx))
}
function getSomeOneName(result){
result.push('Andy');
}
// execute
main();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.js"></script>
</head>
<body>
</body>
</html>
在任何现代浏览器中,您都可以使用 async
/await
来获得同步行为。你必须:
- 将您的
main
声明为 async
- 将
forEach
替换为 for
..of
(回调不适用于 await
)
- 将您的
Observable
转换为 Promise
使其可以等待,然后 return 它
- 将
subscribe
替换为 do
。您仍然会得到副作用,但 do
return 是可观察的,因此您可以立即链接 toPromise
。观察者自动被toPromise
订阅
代码为:
async function main(){
methods = [
getNameFromServer,
getSomeOneName
];
const result = [];
for (let method of methods) {
await method(result);
}
console.log(result);
}
function getNameFromServer(result){
return Rx.Observable.of('John')
.delay(1000)
.do(name => {
console.log('now async get name , but I need it will be sync')
result.push(name)
})
.toPromise();
// can I use sync Ajax like jquery's code?
// $.ajax({
// ... ,
// async: false
// })
// .done(response => result.push(response.xxx))
}
function getSomeOneName(result){
result.push('Andy');
}
// execute
main();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.js"></script>
</head>
<body>
</body>
</html>
我有一些业务逻辑函数要调用,它有一个必须使用 HttpGet 的逻辑,如果我使用 jquery,我必须等到它 returns 结果才能继续ajax可以简单搞定,不知道Observable是否也有类似的做法?
我希望结果是:
- 约翰
- 安迪
但现在结果只显示 Andy :(
function main(){
/*
I have more than 70 sharing rules to deal with different Logic
(e.g. getAge , getSomthing...), in order to simplify the problem ,
I only list two rules as a demonstration
*/
methods = [
getNameFromServer,
getSomeOneName
];
const result = [];
methods.forEach(method => {
method(result);
})
console.log(result);
}
function getNameFromServer(result){
Rx.Observable.of('John')
.delay(1000)
.subscribe(name => {
console.log('now async get name , but I need it will be sync')
result.push(name)
});
// can I use sync Ajax like jquery's code?
// $.ajax({
// ... ,
// async: false
// })
// .done(response => result.push(response.xxx))
}
function getSomeOneName(result){
result.push('Andy');
}
// execute
main();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.js"></script>
</head>
<body>
</body>
</html>
在任何现代浏览器中,您都可以使用 async
/await
来获得同步行为。你必须:
- 将您的
main
声明为async
- 将
forEach
替换为for
..of
(回调不适用于await
) - 将您的
Observable
转换为Promise
使其可以等待,然后 return 它 - 将
subscribe
替换为do
。您仍然会得到副作用,但do
return 是可观察的,因此您可以立即链接toPromise
。观察者自动被toPromise
订阅
代码为:
async function main(){
methods = [
getNameFromServer,
getSomeOneName
];
const result = [];
for (let method of methods) {
await method(result);
}
console.log(result);
}
function getNameFromServer(result){
return Rx.Observable.of('John')
.delay(1000)
.do(name => {
console.log('now async get name , but I need it will be sync')
result.push(name)
})
.toPromise();
// can I use sync Ajax like jquery's code?
// $.ajax({
// ... ,
// async: false
// })
// .done(response => result.push(response.xxx))
}
function getSomeOneName(result){
result.push('Andy');
}
// execute
main();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.js"></script>
</head>
<body>
</body>
</html>