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>