📝

忘れがちな非同期処理

2021/06/18に公開

callback(ES6以前)

非同期処理といえば真っ先に出てくるのはこれかな。

const fs = require('fs');

function read(callback){
  fs.readFile('data.txt', function(data) {
    callback(data);
  });
}

read(function(data){
  console.log(data);
});

ただこれが何層にもなると、いわゆるコールバック地獄となる。

fs.readFile('data1.txt', function(data1) {
  fs.readFile('data2.txt', function(data2) {
    fs.readFile('data3.txt', function(data3) {
      fs.readFile('data4.txt', function(data4) {
        fs.readFile('data5.txt', function(data5) {
          console.log(data1, data2, data3, data4, data5);
        });
      });
    });
  });
});

う...めまいが...

Promise(ES6以降)

Promiseを返すことによって、thenでチェーンすることができる。

function read(str){
  return new Promise(function(resolve, reject){
    fs.readFile(str, function(data) {
      resolve(data);
    });
  });
}

read('data.txt').then(function(data){
  console.log(data);
});

ただこれもチェーンが多くなると、うーん...
しかも各thenの中では、他の引数を参照できない(一度外に出す必要がある)


var d1, d2, d3, d4, d5;

read('data1.txt').then(function(data1){
  d1 = data1
  return read('data2.txt');
}).then(function(data2){
  d2 = data2;
  return read('data3.txt');
}).then(function(data3){
  d3 = data3;
  return read('data4.txt');
}).then(function(data4){
  d4 = data4;
  return read('data5.txt');
}).then(function(data5){
  d5 = data5;
  console.log(d1, d2, d3, d4, d5);
});

async/await(ES8以降)

async関数でラップする + Promiseを返した変数にawaitをつけることで、その後の処理を待たせることができる。

function read(str){
  return new Promise(function(resolve, reject){
    fs.readFile(str, function(data) {
      resolve(data);
    });
  });
}

// async関数でラップする
async function exec(){
  var d1 = await read('data1.txt');
  var d2 = await read('data2.txt');
  var d3 = await read('data3.txt');
  var d4 = await read('data4.txt');
  var d5 = await read('data5.txt');
  console.log(d1, d2, d3, d4, d5);
}
exec();

// もしくは、asyncの即時関数を使う
(async function(){
  var d1 = await read('data1.txt');
  var d2 = await read('data2.txt');
  var d3 = await read('data3.txt');
  var d4 = await read('data4.txt');
  var d5 = await read('data5.txt');
  console.log(d1, d2, d3, d4, d5);
})();

ほっ...

Discussion