亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

javascript - 同步方式寫非同步到底指什麼?
天蓬老師
天蓬老師 2017-07-05 10:52:36
0
4
1249

同步不就是同步,非同步不就是非同步嗎?同步方式寫異步到底指什麼?

天蓬老師
天蓬老師

歡迎選擇我的課程,讓我們一起見證您的進(jìn)步~~

全部回覆(4)
扔個(gè)三星炸死你

非同步呼叫對於當(dāng)前線程來說,是非阻礙的,所以要想知道非同步處理是否完成,或者是否出錯(cuò),通常都是透過事件或回調(diào)來實(shí)現(xiàn)的,這在 Node.js 比比皆是。 Ajax 就是很典型的非同步調(diào)用,以 jQuery.ajax 為例

$.getJSON("http://api.youapp.com/resouce1")
    .done(function(jo) {
        console.log("api resouce1 返回的是", jo);
    });

jQuery 的 Ajax 回傳的是 jQuery 的 Promise 對象,一般習(xí)慣上我們會使用 done() 回呼來處理呼叫完成之後的事情。但實(shí)際它也有標(biāo)準(zhǔn)Promise 的then(),所以上面的done 是可以改成then 的,但是要注意,done 是以事件的形式註冊回調(diào),它返回當(dāng)前這個(gè)Promise 物件,可以鍊式呼叫註冊若干個(gè)回呼。而 then 回傳的是另一個(gè) Promise 物件(標(biāo)準(zhǔn) Promise 規(guī)範(fàn)),鍊式呼叫的話,每次呼叫並非作用在同一個(gè) Promise 物件上。

如果在一個(gè)回調(diào)中需要進(jìn)行另一個(gè)非同步調(diào)用,就需要在回調(diào)中註冊另一個(gè)回調(diào)。例如要取得某個(gè)數(shù)據(jù),就需要先從api1 取得某個(gè)值,再用這個(gè)值去api2 取得某個(gè)資源,再用這個(gè)資源中的某個(gè)值去api3 取得這個(gè)值,這樣的回呼寫出來會像這樣:

$.getJSON("http://api.youapp.com/resouce1")
    .then(function(jo) {
        $.getJSON("http://api.youapp.com/resouce2?id=" + jo.blaId)
            .then(function(jo2) {
                $.getJSON("http://api.youapp.com/resouce3?xxx=" + jo2.xxxValue)
                    .then(function(value) {
                        console.log("總算拿到了", value);
                    });
            });
    });

這才三層……很可怕的形式。這種形式被稱為「回調(diào)地獄」。

大家想了很多辦法來解決這種問題,Promise 就是其一,但是 Promise 仍然無法完全擺脫這種形式。 co 庫也是解決方案之一,同樣無法完美擺脫。

不過 ES2017 引入了 async/await,也就是所謂的以同步的形式寫異步,例如上面那段程式碼可以改寫成


async function xxx() {
    const jo = await $.getJSON("http://api.youapp.com/resouce1");
    const jo2 = await $.getJSON("http://api.youapp.com/resouce2?id=" + jo.blaId);
    const value = await $.getJSON("http://api.youapp.com/resouce3?xxx=" + jo2.xxxValue);
    console.log("總算拿到了", value);
}

async/await 消除了回調(diào),所以看起來跟寫非異步(即同步)程式碼一樣。

參考:

  • 閒聊非同步調(diào)用「扁平」化

  • 從地獄到天堂,Node 回調(diào)轉(zhuǎn)向 async/await

  • 理解 JavaScript 的 async/await

Ty80

非同步時(shí)常見回呼函數(shù)嵌套,形如:

// 先讀取 a
fs.readFile('a.txt', (a) => {
  // a 讀取成功后讀取 b
  fs.readFile('b.txt', (b) => {
    // b 讀取成功后讀取 c
    fs.readFile('c.txt'. (c) => {
      console.log(a + b + c)
    })
  })
})

這時(shí)出現(xiàn)了回調(diào)嵌套,需要一層一層往裡套,非常容易出錯(cuò)且不好維護(hù)。

同步方式寫非同步類似:

function * asyncWrapper () {
  const a = yield read('a.txt')
  const b = yield read('b.txt')
  const c = yield read('c.txt')
  console.log(a + b + c)
}
// 使用形如 co 的庫自動執(zhí)行異步邏輯
co(asyncWrapper)

這時(shí)候非同步業(yè)務(wù)邏輯就透過正常的同步方式實(shí)現(xiàn)了。

我想大聲告訴你

同步方式寫非同步指得是程式碼的組織形式而已。使用async/await可以實(shí)現(xiàn)同步方式寫非同步,看下面程式碼:

const testAsync = async () => {
  const t = await f();
  console.log(t);
};

testAsync();

f是一個(gè)非同步操作,如果不使用async/await,直接同步的方式列印t,結(jié)果肯定是undefined;使用async/await之後,程式碼看上去形式還是同步的,但是裡面是先執(zhí)行異步操作f,再印t的

伊謝爾倫

樓上兩個(gè)答案足矣

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板