js同步-異步-回調

出處:https://blog.csdn.net/u010297791/article/details/71158212
(1)上面主要講了同步和回調執行順序的問題,接着我就舉一個包含同步、異步、回調的例子。html

    let a = new Promise(//聲明瞭一個Promise回調函數,可以使用then
  function(resolve, reject) {
    console.log(1)
    setTimeout(() => console.log(2), 0)
    console.log(3)
    console.log(4)
    resolve(true)
  }
)
a.then(v => {
  console.log(8)
})
 
let b = new Promise(
  function() {
    console.log(5)
    setTimeout(() => console.log(6), 0)
  }
)
 
console.log(7)


     在看正確結果以前,我先進行分析題目(訪問順序:同步 => 異步 => 回調):
    1)看同步代碼:a變量是一個Promise,Promise的異步指的是他的then()和catch()方法,Promise自己仍是同步的,因此這裏先執行a變量內部的Promise同步代碼。(同步優先)
    console.log(1)
    setTimeout(() => console.log(2), 0) //回調
    console.log(3)
    console.log(4)
    2)Promise內部有4個console,第二個是一個setTimeout回調(回調墊底(意思就是你先讓它等着),因此暫時不輸出)。因此這裏先輸出1,3,4,回調的方法丟到消息隊列中排隊等着。
    3)接着執行resolve(true),進入then(),then是異步,下面還有同步沒執行完呢,因此then也去消息隊列排隊等候。(異步靠邊)
    4)b變量也是一個Promise,和a同樣,一樣是同步的,執行內部的同步代碼,輸出5,setTimeout是回調,去消息隊列排隊等候,這裏輸出5。
    5)最下面同步輸出7。
    6)如今同步的代碼執行完了,JavaScript就跑去消息隊列呼叫異步的代碼:異步,出來執行了。這裏只有一個異步then,因此輸出8。
   7)此時,異步也over,輪到回調函數:回調,出來執行了。這裏有2個回調在排隊,他們的時間都設置爲0,因此不受時間影響,只跟排隊前後順序有關。則先輸出a裏面的回調2,最後輸出b裏面的回調6。
   8)最終輸出結果就是:一、三、四、五、七、八、二、6。

(2)分析下面這個例子的執行順序promise

var Pro = function () {
   //返回一個Promise對象
   return new Promise(function (resolve, reject) {
    //模擬接口調用
    setTimeout(function () {//1,回調等待,同步執行
     resolve(true);//4,而後進入then函數
    }, 1000);
   })
  };
  var Pro2 = function () {
   //返回一個Promise對象
   return new Promise(function (resolve, reject) {
    //模擬接口調用
    setTimeout(function () {//2,回調等待
     resolve(‘Pro2成功執行’);//9,訪問另外一個then
    }, 1000);
   })
  };
  
  Pro().then(function(data){//3異步等待
   var val = data;//5,resolve傳入的data是true
   console.log(val)//6,因此先輸出true
   if (val) {
    console.log(1111)//7,再輸出1111
    return Pro2()//8
   }
   
  }).then(function(data1){//8異步等待
   console.log(data1)//10,輸出Pro2成功執行
  })

輸出:
異步


(3)async/await(代替了promise)
能夠先看http://www.ruanyifeng.com/blog/2015/05/async.html
async 函數返回一個 Promise 對象,可使用 then 方法添加回調函數。當函數執行的時候,一旦遇到 await 就會先返回,等到觸發的異步操做完成,再接着執行函數體內後面的語句。
下面是一個例子。
//getStockSymbol(name)和getStockPrice(symbol)都是異步函數,這樣才能使用
//await進行聲明,當兩個異步函數調用完後,返回一個Promise對象,其值爲
//stockPrice
async function getStockPriceByName(name) {
  var symbol = await getStockSymbol(name);
  var stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

//而後就可使用then函數來獲得返回的值result == stockPrice
getStockPriceByName('goog').then(function (result){
  console.log(result);
});


//若是在函數function (result){}中運行了比較複雜的語句最好是加上catch來捕獲err,如:
getStockPriceByName('goog').then(function (result){
  console.log(result);
}).catch((err) =>{
    console.log(err);
        });

上面代碼是一個獲取股票報價的函數,函數前面的async關鍵字,代表該函數內部有異步操做。調用該函數時,會當即返回一個Promise對象。

這個東西的使用手法就是:
首先你先寫一個return new Promise的回調function,這個function就不用聲明爲async,而後就能夠在另外一個聲明爲async的函數中使用這個回調function ,使用時前面代表await,await等待的雖然是promise對象,但沒必要寫.then(..),直接能夠獲得返回值;另外一個使用的辦法則是直接使用then函數回調,而後用catch函數捕捉錯誤。


在async函數中若是有await的聲明,只能說後面要進行的操做是異步操做來得到返回值的,若是前後,如:
   async

let c = await count();

    函數

let l = await list();
return {count:c,list:l};
只是說明二者只是寫的時候好像有了個先後關係,可是他們不是同步的,而是異步的,因此他們能夠同時進行運算,而後等待二者結果都出來了之後進行拼裝罷了


當函數執行的時候,一旦遇到 await 就會先返回,等到觸發的異步操做完成,再接着執行函數體內後面的語句

我是這麼理解promise和async/await二者的使用的,我以爲當要使用過多異步的時候,使用async/await更好,好比:測試

var id;
create(user1,’0x0000002’,10,10).then((result) => {
    if(result){
        console.log(result);
        return owned(user1);  //獲得user1建立的tokenID
    }
}).then((result) => {
    if(result){
        id = result;
        console.log('num is :' + result);
        return sell(result);  //賣掉該token
    }   
}).then((result) => {
    if(result){
        console.log(result);
        return buy(user2,40,id);  
    }       
}).catch((err) =>{
    console.log(err);
});


當咱們想要對一系列回調函數進行有序測試時,若是使用的是then,那麼最後看起來真的很繁雜;可是若是使用的是async/await,那麼就能夠變成:spa

var test = async() => {
    try{
        await create(user1,’0x0000002’,10,10);
        var id = await owned(user1);
        await sell(id);
        await buy(user2,40,id);
    }catch(err){
        console.log(err);
    }
}

光是看起來就好不少了

注意:當一個函數被聲明爲async時,說明它是異步的,說明它的返回值是promise類型的,調用函數後後面能夠用then進行返回值的調用,而不是說它的函數中必定要出現await。


.net

相關文章
相關標籤/搜索