Skip to content

六种异步方案:

  • 回调函数
  • 事件监听
  • 发布/订阅
  • Promise
  • Generator
  • Async

异步方案

异步处理的几种方式

题目:红灯三秒亮一次,绿灯一秒亮一次,黄灯两秒亮一次,不断交替循环

js
// 先定义下红绿灯:
function red() {
  console.log("red");
}
function green() {
  console.log("green");
}
function yellow() {
  console.log("yellow");
}

回调函数

这是最常见的一种方式,把函数作为参数送入,然后回调。

js
// 封装定时器
var light = (timmer, cb) => {
  setTimeout(() => {
    cb();
  }, timmer);
};

function step(cb) {
  light(3000, () => {
    red();
    light(1000, () => {
      green();
      light(2000, () => {
        yellow();
        step();
      });
    });
  });
  typeof cb === "function" && cb();
}

step(() => console.log("wait for about 3 seconds..."));

事件监听

采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。监听一个事件,然后触发这个事件,并且执行事件里的回调函数

js
// 引入 Node events 模块
const events = require("events");
const emitter = new events.EventEmitter();

// 封装定时器
const lightHandler = (timmer, cb) => {
  setTimeout(() => {
    cb();
  }, timmer);
};

// 监听
emitter.on("lightEvent", str => console.log(str));

// 触发
function step() {
  lightHandler(3000, () => {
    emitter.emit("lightEvent", "red");
    lightHandler(1000, () => {
      emitter.emit("lightEvent", "green");
      lightHandler(2000, () => {
        emitter.emit("lightEvent", "yellow");
        step();
      });
    });
  });
}

step();

Promise

js
var light = (timmer, cb) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      cb();
      resolve();
    }, timmer);
  });
};

var step = () => {
  Promise.resolve()
    .then(() => {
      return light(3000, red);
    })
    .then(() => {
      return light(1000, green);
    })
    .then(() => {
      return light(2000, yellow);
    })
    .then(() => {
      step();
    })
    .catch(err => console.log(err));
};

step();

Generator

js
const light = (timmer, cb) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      cb();
      resolve();
    }, timmer);
  });
};

function* gen() {
  yield light(3000, red);
  yield light(1000, green);
  yield light(3000, yellow);
}

const iterator = gen();

const step = (gen, iterator) => {
  const s = iterator.next();
  // 返回 { value: Promise { <pending> }, done: false }
  if (s.done) {
    step(gen, gen());
  } else {
    // value 返回 Promise 对象
    s.value.then(() => {
      step(gen, iterator);
    });
  }
};

step(gen, iterator);

Async/await

js
const light = (timmer, cb) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      cb();
      resolve();
    }, timmer);
  });
};

async function step() {
  await light(3000, red);
  await light(1000, green);
  await light(2000, yellow);
  step();
}

step();