成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

異步

TalkingData / 2502人閱讀

摘要:回調(diào)的問(wèn)題異常處理異步代碼時(shí)不再生效捕獲錯(cuò)誤因?yàn)檫@個(gè)回調(diào)函數(shù)被存放了起來(lái),直到下一個(gè)事件環(huán)的時(shí)候才會(huì)取出只能捕獲當(dāng)前循環(huán)內(nèi)的異常,對(duì)異步無(wú)能為力。

異步
所謂"異步",簡(jiǎn)單說(shuō)就是一個(gè)任務(wù)分成兩段,先執(zhí)行第一段,然后轉(zhuǎn)而執(zhí)行其他任務(wù),等做好了準(zhǔn)備,再回過(guò)頭執(zhí)行第二段,比如,有一個(gè)任務(wù)是讀取文件進(jìn)行處理,異步的執(zhí)行過(guò)程就是下面這樣。

這種不連續(xù)的執(zhí)行,就叫做異步。相應(yīng)地,連續(xù)的執(zhí)行,就叫做同步。

高階函數(shù)
函數(shù)作為一等公民,可以作為參數(shù)和返回值
可以用于批量生成函數(shù)
let toString = Object.prototype.toString;
let isString = function (obj) {
  return toString.call(obj) == `[object String]`;
}
let isFunction = function (obj) {
  return toString.call(obj) == `[object Function]`;
}
let isType = function (type) {
  return function (obj) {
    return toString.call(obj) == `[object ${type}]`;
  }
}
可以用于需要調(diào)用多次才執(zhí)行的函數(shù)
let after = function(times,task){
  return function(){
    if(times--==1){
      return task.apply(this,arguments);
    }
  }
}
let fn = after(3,function(){
  console.log(3);});
fn();
異步編程的語(yǔ)法目標(biāo),就是怎樣讓它更像同步編程,有以下幾種

回調(diào)函數(shù)實(shí)現(xiàn)

事件監(jiān)聽(tīng)

發(fā)布訂閱

Promise/A+ 和生成器函數(shù)

async/await

回調(diào)
所謂回調(diào)函數(shù),就是把任務(wù)的第二段多帶帶寫(xiě)在一個(gè)函數(shù)里面,等到重新執(zhí)行這個(gè)任務(wù)的時(shí)候,就直接調(diào)用這個(gè)函數(shù)
fs.readFile("某個(gè)文件", function (err, data) {
  if (err) throw err;
  console.log(data);
});

這是一個(gè)錯(cuò)誤優(yōu)先的回調(diào)函數(shù)(error-first callbacks),這也是Node.js本身的特點(diǎn)之一。

回調(diào)的問(wèn)題 異常處理
try{
  //xxx
}catch(e){//TODO}
異步代碼時(shí)try catch不再生效

let async = function(callback){
  try{
    setTimeout(function(){
      callback();
    },1000)
  }catch(e){
    console.log("捕獲錯(cuò)誤",e);
  }
}

async(function(){
  console.log(t);
});

因?yàn)檫@個(gè)回調(diào)函數(shù)被存放了起來(lái),直到下一個(gè)事件環(huán)的時(shí)候才會(huì)取出,try只能捕獲當(dāng)前循環(huán)內(nèi)的異常,對(duì)callback異步無(wú)能為力。

Node在處理異常有一個(gè)約定,將異常作為回調(diào)的第一個(gè)實(shí)參傳回,如果為空表示沒(méi)有出錯(cuò)。

async(function(err,callback){
  if(err){
    console.log(err);
  }
});
異步方法也要遵循兩個(gè)原則

必須在異步之后調(diào)用傳入的回調(diào)函數(shù)

如果出錯(cuò)了要向回調(diào)函數(shù)傳入異常供調(diào)用者判斷

let async = function(callback){
try{
  setTimeout(function(){
    if(success)
      callback(null);
    else
      callback("錯(cuò)誤");
  },1000)
}catch(e){
  console.log("捕獲錯(cuò)誤",e);
}
}
回調(diào)地獄
異步多級(jí)依賴(lài)的情況下嵌套非常深,代碼難以閱讀的維護(hù)
let fs = require("fs");
fs.readFile("template.txt","utf8",function(err,template){
fs.readFile("data.txt","utf8",function(err,data){
  console.log(template+" "+data);
})
})
異步流程解決方案 事件發(fā)布/訂閱模型
訂閱事件實(shí)現(xiàn)了一個(gè)事件與多個(gè)回調(diào)函數(shù)的關(guān)聯(lián)
let fs = require("fs");
let EventEmitter = require("events");
let eve = new EventEmitter();
let html = {};
eve.on("ready",function(key,value){
  html[key] = value;
  if(Object.keys(html).length==2){
    console.log(html);
  }
});
function render(){
  fs.readFile("template.txt","utf8",function(err,template){
    eve.emit("ready","template",template);
  })
  fs.readFile("data.txt","utf8",function(err,data){
    eve.emit("ready","data",data);
  })
}
render();
哨兵變量
let fs = require("fs");

let after = function(times,callback){
  let result = {};
  return function(key,value){
    result[key] = value;
    if(Object.keys(result).length==times){
      callback(result);
    }
  }
}
let done = after(2,function(result){
  console.log(result);
});

function render(){
  fs.readFile("template.txt","utf8",function(err,template){
    done("template",template);
  })
  fs.readFile("data.txt","utf8",function(err,data){
    done("data",data);
  })
}
rende
Promise/Deferred模式 生成器Generators/ yield
當(dāng)你在執(zhí)行一個(gè)函數(shù)的時(shí)候,你可以在某個(gè)點(diǎn)暫停函數(shù)的執(zhí)行,并且做一些其他工作,然后再返回這個(gè)函數(shù)繼續(xù)執(zhí)行, 甚至是攜帶一些新的值,然后繼續(xù)執(zhí)行。

上面描述的場(chǎng)景正是JavaScript生成器函數(shù)所致力于解決的問(wèn)題。當(dāng)我們調(diào)用一個(gè)生成器函數(shù)的時(shí)候,它并不會(huì)立即執(zhí)行, 而是需要我們手動(dòng)的去執(zhí)行迭代操作(next方法)。也就是說(shuō),你調(diào)用生成器函數(shù),它會(huì)返回給你一個(gè)迭代器。迭代器會(huì)遍歷每個(gè)中斷點(diǎn)。
next方法返回值的value屬性,是Generator函數(shù)向外輸出數(shù)據(jù)next方法還可以接受參數(shù),這是向 Generator 函數(shù)體內(nèi)輸入數(shù)據(jù)

生成器的使用
function* foo () {
  var index = 0;
  while (index < 2) {
    yield index++; //暫停函數(shù)執(zhí)行,并執(zhí)行yield后的操作
  }
}
var bar =  foo(); // 返回的其實(shí)是一個(gè)迭代器

console.log(bar.next());    // { value: 0, done: false }
console.log(bar.next());    // { value: 1, done: false }
console.log(bar.next());    // { value: undefined, done: true }
Co

co是一個(gè)為Node.js和瀏覽器打造的基于生成器的流程控制工具,借助于Promise,你可以使用更加優(yōu)雅的方式編寫(xiě)非阻塞代碼。

let fs = require("fs");
function readFile(filename) {
  return new Promise(function (resolve, reject) {
    fs.readFile(filename, function (err, data) {
      if (err)
        reject(err);
      else
        resolve(data);
    })
  })
}
function *read() {
  let template = yield readFile("./template.txt");
  let data = yield readFile("./data.txt");
  return template + "+" + data;
}
co(read).then(function (data) {
  console.log(data);
}, function (err) {
  console.log(err);
});
function co(gen) {
  let it = gen();
  return new Promise(function (resolve, reject) {
    !function next(lastVal) {
      let {value, done} = it.next(lastVal);
      if (done) {
        resolve(value);
      } else {
        value.then(next, reason => reject(reason));
      }
    }();
  });
}
Async/ await
使用async關(guān)鍵字,你可以輕松地達(dá)成之前使用生成器和co函數(shù)所做到的工作

Async的優(yōu)點(diǎn)

內(nèi)置執(zhí)行器

更好的語(yǔ)義

更廣的適用性

let fs = require("fs");
function readFile(filename) {
  return new Promise(function (resolve, reject) {
    fs.readFile(filename, "utf8", function (err, data) {
      if (err)
        reject(err);
      else
        resolve(data);
    })
  })
}

async function read() {
  let template = await readFile("./template.txt");
  let data = await readFile("./data.txt");
  return template + "+" + data;
}
let result = read();
result.then(data=>console.log(data));
async 函數(shù)的實(shí)現(xiàn)

async 函數(shù)的實(shí)現(xiàn),就是將 Generator 函數(shù)和自動(dòng)執(zhí)行器,包裝在一個(gè)函數(shù)里。

async function read() {
  let template = await readFile("./template.txt");
  let data = await readFile("./data.txt");
  return template + "+" + data;
}
// 等同于
function read(){
  return co(function*() {
    let template = yield readFile("./template.txt");
    let data = yield readFile("./data.txt");
    return template + "+" + data;
  });
}
async_function- generator

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101790.html

相關(guān)文章

  • JavaScript 異步時(shí)序問(wèn)題

    摘要:異步時(shí)序問(wèn)題吾輩的博客原文場(chǎng)景死后我們必升天堂,因?yàn)榛顣r(shí)我們已在地獄。關(guān)鍵點(diǎn)異步操作得到結(jié)果的時(shí)間順序是不確定的如果觸發(fā)事件的頻率較高異步操作的時(shí)間過(guò)長(zhǎng)出現(xiàn)這種問(wèn)題怎么解決既然關(guān)鍵點(diǎn)由兩個(gè)要素組成,那么,只要破壞了任意一個(gè)即可。 JavaScript 異步時(shí)序問(wèn)題 吾輩的博客原文:https://blog.rxliuli.com/p/de... 場(chǎng)景 死后我們必升天堂,因?yàn)榛顣r(shí)我們已...

    tuantuan 評(píng)論0 收藏0
  • 同步與異步異步與回調(diào)

    摘要:同步與異步以上為同步代碼,函數(shù)必須等函數(shù)執(zhí)行完畢后才能執(zhí)行。異步回調(diào)產(chǎn)生的結(jié)果就是,函數(shù)的調(diào)用并不直接返回結(jié)果,而往往是交給回調(diào)函數(shù)進(jìn)行異步處理。 同步與異步: function a(){} function b(){} a(); b(); 以上為同步代碼,函數(shù)b必須等函數(shù)a執(zhí)行完畢后才能執(zhí)行。 function a(){ ...

    dinfer 評(píng)論0 收藏0
  • 異步!異步!異步

    摘要:同步和異步先說(shuō)個(gè)傻子的故事有個(gè)傻子,第一次用某雷下載大片,就是大人看的片,咳咳咳。。。 1.同步和異步 1.1先說(shuō)個(gè)傻子的故事 有個(gè)傻子,第一次用某雷下載大片,就是大人看的片,咳咳咳。。。 某雷告訴他,下載時(shí)間要倆小時(shí),傻子心想,要倆小時(shí)吶,我第一次用某雷,我得盯著它下載,啥也不能干 于是傻子就干瞪著電腦,等著片下完,這倆小時(shí),傻子啥也沒(méi)干 后來(lái),傻子變聰明了,他想,反正某雷在幫他下...

    ThinkSNS 評(píng)論0 收藏0
  • 異步!異步異步!

    摘要:同步和異步先說(shuō)個(gè)傻子的故事有個(gè)傻子,第一次用某雷下載大片,就是大人看的片,咳咳咳。。。 1.同步和異步 1.1先說(shuō)個(gè)傻子的故事 有個(gè)傻子,第一次用某雷下載大片,就是大人看的片,咳咳咳。。。 某雷告訴他,下載時(shí)間要倆小時(shí),傻子心想,要倆小時(shí)吶,我第一次用某雷,我得盯著它下載,啥也不能干 于是傻子就干瞪著電腦,等著片下完,這倆小時(shí),傻子啥也沒(méi)干 后來(lái),傻子變聰明了,他想,反正某雷在幫他下...

    chanthuang 評(píng)論0 收藏0
  • (轉(zhuǎn))JavaScript:同步、異步和事件循環(huán)

    摘要:事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過(guò)程。事件觸發(fā)時(shí),表示異步任務(wù)完成,會(huì)將事件監(jiān)聽(tīng)器函數(shù)封裝成一條消息放到消息隊(duì)列中,等待主線程執(zhí)行。 一. 單線程 我們常說(shuō)JavaScript是單線程的。 所謂單線程,是指在JS引擎中負(fù)責(zé)解釋和執(zhí)行JavaScript代碼的線程只有一個(gè)。不妨叫它主線程。 但是實(shí)際上還存在其他的線程。例如:處理AJAX請(qǐng)求的線程、處理DOM事件的線...

    android_c 評(píng)論0 收藏0
  • JavaScript:徹底理解同步、異步和事件循環(huán)(Event Loop)

    摘要:例如處理請(qǐng)求的線程處理事件的線程定時(shí)器線程讀寫(xiě)文件的線程例如在中等等。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過(guò)程。事件觸發(fā)時(shí),表示異步任務(wù)完成,會(huì)將事件監(jiān)聽(tīng)器函數(shù)封裝成一條消息放到消息隊(duì)列中,等待主線程執(zhí)行。 一. 單線程 我們常說(shuō)JavaScript是單線程的。 所謂單線程,是指在JS引擎中負(fù)責(zé)解釋和執(zhí)行JavaScript代碼的線程只有一個(gè)。不妨叫它主線程。 但是實(shí)...

    wenyiweb 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<