js同步-非同步-回調

來源:互聯網
上載者:User

標籤:bubuko   div   wait   syn   代碼執行   color   rip   時間   UNC   

出處:71158212
(1)上面主要講了同步和回調執行順序的問題,接著我就舉一個包含同步、非同步、回調的例子。

    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)最終輸出結果就是:1、3、4、5、7、8、2、6。

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

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的聲明,只能說後面要進行的操作是非同步作業來獲得傳回值的,如果先後,如:?   

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,那麼就可以變成:

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。


js同步-非同步-回調

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.