ES6 학습--비동기식 프로그래밍--async

4819 단어

async 함수


async, 비동기 함수의 궁극적인 해결 방안이라고 합니다!본질은Generator의 문법당이다.
어떻게 읽을지 궁금해하는 친구들이 있을 거예요. 여기 특별히 음표를 보충해 드릴게요.ə'zɪŋk]
Generator :
var fs = require('fs');

var readFile = function (fileName){
  return new Promise(function (resolve, reject){
    fs.readFile(fileName, function(error, data){
      if (error) reject(error);
      resolve(data);
    });
  });
};

var gen = function* (){
  var f1 = yield readFile('/etc/fstab');
  var f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

async :
var asyncReadFile = async function (){
  var f1 = await readFile('/etc/fstab');
  var f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

async 함수는Generator 함수의 별표 (*) 를 async로 바꾸고 yield를 await로 바꾸는 것입니다.

이점

  • 내장형 집행기.Generator 함수의 실행은 실행기에 의존해야 하기 때문에co 함수 라이브러리가 있고 async 함수는 실행기를 가지고 있습니다.
  • 더 좋은 의미.async는 함수에 비동기적인 조작이 있음을 나타내고await는 뒤에 바짝 붙어 있는 표현식이 결과를 기다려야 한다는 것을 나타낸다.
  • 더욱 광범위한 적용성.co 함수 라이브러리는 yield 명령 뒤에는 Thunk 함수나 Promise 대상만 있을 수 있고, async 함수의await 명령 뒤에는 Promise 대상과 원시 형식의 값(수치, 문자열, 부울 값만 있을 수 있지만, 이때는 동기화 작업과 같다)을 지정할 수 있다고 약정했다.

  • 원리


    async 함수의 실현은Generator 함수와 자동 집행기를 하나의 함수에 포장하는 것이다.
    async function fn(args){
      // ...
    }
    //  
    function fn(args){ 
      return spawn(function*() {
        // ...
      }); 
    }
    

    모든 async 함수는 위의 두 번째 형식으로 쓸 수 있는데, 그 중spawn 함수는 바로 자동 집행기이다.다음은spawn 함수의 실현을 제시하는데 기본적으로 앞의 자동 집행기의 복제판이다.
    function spawn(genF) {
      return new Promise(function(resolve, reject) {
        var gen = genF();
        function step(nextF) {
          try {
            var next = nextF();
          } catch(e) {
            return reject(e); 
          }
          if(next.done) {
            return resolve(next.value);
          } 
          Promise.resolve(next.value).then(function(v) {
            step(function() { return gen.next(v); });      
          }, function(e) {
            step(function() { return gen.throw(e); });
          });
        }
        step(function() { return gen.next(undefined); });
      });
    }
    

    async 함수는 매우 새로운 문법 기능으로 ES6가 아니라 ES7에 속한다.현재, 그것은 여전히 제안 단계에 있지만, 디코더 Babel과regenerator는 이미 지원하고, 디코딩 후에 사용할 수 있다.

    활용단어참조


    Generator 함수와 마찬가지로 async 함수는 Promise 대상을 되돌려줍니다. then 방법으로 리셋 함수를 추가할 수 있습니다.함수가 실행될 때, await를 만나면 먼저 되돌아오고, 촉발된 비동기적인 조작이 끝날 때까지 기다렸다가 함수 체내 뒤의 문장을 실행합니다.
    async function getStockPriceByName(name) {
      var symbol = await getStockSymbol(name);
      var stockPrice = await getStockPrice(symbol);
      return stockPrice;
    }
    
    getStockPriceByName('goog').then(function (result){
      console.log(result);
    });
    

    위 코드는 주식 가격을 얻는 함수입니다. 함수 앞의 async 키워드는 이 함수 내부에 비동기적인 조작이 있음을 나타냅니다.이 함수를 호출하면 Promise 객체가 즉시 반환됩니다.
    function timeout(ms) {
      return new Promise((resolve) => {
        setTimeout(resolve, ms);
      });
    }
    
    async function asyncPrint(value, ms) {
      await timeout(ms);
      console.log(value)
    }
    
    asyncPrint('hello world', 50);
    

    위 코드가 50밀리초를 지정한 후에 "hello world"를 출력합니다.

    주의하다


    await 명령 뒤에 있는 Promise 대상, 실행 결과는rejected일 수 있으므로 await 명령을try에 두는 것이 좋습니다.catch 코드 블록에 있습니다.
    async function myFunction() {
      try {
        await somethingThatReturnsAPromise();
      } catch (err) {
        console.log(err);
      }
    }
    //  
    async function myFunction() {
      await somethingThatReturnsAPromise().catch(function (err){
        console.log(err);
      });
    }
    

    await 명령은 async 함수에만 사용할 수 있으며, 일반 함수에만 사용하면 오류가 발생합니다.
    async function dbFuc(db) {
      let docs = [{}, {}, {}];
    
      //  
      docs.forEach(function (doc) {
        await db.post(doc);
      });
    }
    

    위의 코드는 일반 함수에 사용되기 때문에 오류를 보고할 수 있습니다.그러나 forEach 방법의 매개 변수를 async 함수로 바꾸면 문제가 있습니다.
    async function dbFuc(db) {
      let docs = [{}, {}, {}];
    
      //  
      docs.forEach(async function (doc) {
        await db.post(doc);
      });
    }
    

    위의 코드가 정상적으로 작동하지 않을 수도 있습니다. 왜냐하면 이때db가 세 개이기 때문입니다.post 작업은 병렬 실행, 즉 동시 실행이지 계발 실행이 아니다.정확한 작법은 for순환을 채택하는 것이다.
    async function dbFuc(db) {
      let docs = [{}, {}, {}];
    
      for (let doc of docs) {
        await db.post(doc);
      }
    }
    

    여러 요청이 동시에 실행되기를 원하는 경우 Promise를 사용할 수 있습니다.all 방법.
    async function dbFuc(db) {
      let docs = [{}, {}, {}];
      let promises = docs.map((doc) => db.post(doc));
    
      let results = await Promise.all(promises);
      console.log(results);
    }
    //  
    async function dbFuc(db) {
      let docs = [{}, {}, {}];
      let promises = docs.map((doc) => db.post(doc));
    
      let results = [];
      for (let promise of promises) {
        results.push(await promise);
      }
      console.log(results);
    }
    

    참고http://www.ruanyifeng.com/blog

    좋은 웹페이지 즐겨찾기