js 非同步發展過程

码农-编程小子發表於2024-03-21
yield
    return promoise
next引數
    next方法可以帶一個引數,該引數就會被當作上一個yield表示式的返回值
next


01_callbackhell

let sayhello = function (name, callback) {
  setTimeout(function () {
    console.log(name);
    callback();
  }, 1000);
};
sayhello("first", function () {
  sayhello("second", function () {
    sayhello("third", function () {
      console.log("end");
    });
  });
});

02_promise.js

var sayhello = function (name) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log(name);
      resolve();
    }, 1000);
  });
};
sayhello("first")
  .then(function () {
    return sayhello("second");
  })
  .then(function () {
    return sayhello("third");
  })
  .then(function () {
    console.log("end");
  })
  .catch(function (err) {
    console.log(err);
  });

03_generate.js

var sayhello = function (name) {
    return new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log(name);
        resolve();
      }, 1000);
    });
  };

function * genFun(){
    yield sayhello('first');
    yield sayhello('second');
    yield sayhello('third');
}


 
function co(g) {
    let nextObj = g.next();
    if (nextObj.done) {
      return true;
    } else {
      let v = nextObj.value;
      if (typeof v !== Promise) {
        v = Promise.resolve(v);
      }
      v.then((v) => co(g));
    }
  }

  co(genFun())

  04_await.js

  var sayhello = function (name) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log(name);
      resolve();
    }, 1000);
  });
};

async function genFun() {
  await sayhello("first");
  await sayhello("second");
  await sayhello("third");
}

genFun();

05_co.js
/**
 * co function
 * Generator-based Control Flow
 */


function* gen(x) {
  console.log("start");
  yield new Promise((res, rej) => {
    setTimeout(() => {
      res("p1");
    }, 2000);
  });
  console.log("1");

  yield new Promise((res, rej) => {
    setTimeout(() => {
      res("p2");
    }, 1000);
  });
  console.log("2");
  return "end";
}


function co(g) {
  let nextObj = g.next();
  if (nextObj.done) {
    return true;
  } else {
    let v = nextObj.value;
    if (typeof v !== Promise) {
      v = Promise.resolve(v);
    }
    v.then((v) => co(g));
  }
}
var g = myGenerator();
co(g);

06_compile.js

function delay(ms) {
    return new Promise((res, rej) => {
        setTimeout(() => {
            res(true);
        }, ms);
    });
}

async function test(){
    console.log('start');
    await delay(1000)
    console.log('1');
    await delay(1000)
    console.log('2');
    await delay(1000)
    console.log('3');
    await delay(1000)
    console.log('end');
}
after compile

"use strict";
var __awaiter =
  (this && this.__awaiter) ||
  function (thisArg, _arguments, P, generator) {
    function adopt(value) {
      return value instanceof P
        ? value
        : new P(function (resolve) {
            resolve(value);
          });
    }
    return new (P || (P = Promise))(function (resolve, reject) {
      function fulfilled(value) {
        try {
          step(generator.next(value));
        } catch (e) {
          reject(e);
        }
      }
      function rejected(value) {
        try {
          step(generator["throw"](value));
        } catch (e) {
          reject(e);
        }
      }
      function step(result) {
        result.done
          ? resolve(result.value)
          : adopt(result.value).then(fulfilled, rejected);
      }
      let r=(generator = generator.apply(thisArg, _arguments || [])).next()
      step(r);
    });
  };
var __generator =
  (this && this.__generator) ||
  function (thisArg, body) {
    var _ = {
        label: 0,
        sent: function () {
          if (t[0] & 1) throw t[1];
          return t[1];
        },
        trys: [],
        ops: [],
      },
      f,
      y,
      t,
      g;
    return (
      (g = { next: verb(0), throw: verb(1), return: verb(2) }),
      typeof Symbol === "function" &&
        (g[Symbol.iterator] = function () {
          return this;
        }),
      g
    );
    function verb(n) {
      return function (v) {
        return step([n, v]);
      };
    }
    function step(op) {
      if (f) throw new TypeError("Generator is already executing.");
      while ((g && ((g = 0), op[0] && (_ = 0)), _))
        try {
          if (
            ((f = 1),
            y &&
              (t =
                op[0] & 2
                  ? y["return"]
                  : op[0]
                  ? y["throw"] || ((t = y["return"]) && t.call(y), 0)
                  : y.next) &&
              !(t = t.call(y, op[1])).done)
          )
            return t;
          if (((y = 0), t)) op = [op[0] & 2, t.value];
          switch (op[0]) {
            case 0:
            case 1:
              t = op;
              break;
            case 4:
              _.label++;
              return { value: op[1], done: false };
            case 5:
              _.label++;
              y = op[1];
              op = [0];
              continue;
            case 7:
              op = _.ops.pop();
              _.trys.pop();
              continue;
            default:
              if (
                !((t = _.trys), (t = t.length > 0 && t[t.length - 1])) &&
                (op[0] === 6 || op[0] === 2)
              ) {
                _ = 0;
                continue;
              }
              if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
                _.label = op[1];
                break;
              }
              if (op[0] === 6 && _.label < t[1]) {
                _.label = t[1];
                t = op;
                break;
              }
              if (t && _.label < t[2]) {
                _.label = t[2];
                _.ops.push(op);
                break;
              }
              if (t[2]) _.ops.pop();
              _.trys.pop();
              continue;
          }
          op = body.call(thisArg, _);
        } catch (e) {
          op = [6, e];
          y = 0;
        } finally {
          f = t = 0;
        }
      if (op[0] & 5) throw op[1];
      return { value: op[0] ? op[1] : void 0, done: true };
    }
  };
function delay(ms) {
  return new Promise(function (res, rej) {
    setTimeout(function () {
      res(true);
    }, ms);
  });
}
function test() {
  return __awaiter(this, void 0, void 0, function () {
    return __generator(this, function (_a) {
      switch (_a.label) {
        case 0:
          console.log("start");
          return [4 /*yield*/, delay(1*1000)];
        case 1:
          _a.sent();
          console.log("1");
          return [4 /*yield*/, delay(1000)];
        case 2:
          _a.sent();
          console.log("2");
          return [4 /*yield*/, delay(1000)];
        case 3:
          _a.sent();
          console.log("3");
          return [4 /*yield*/, delay(1000)];
        case 4:
          _a.sent();
          console.log("end");
          return [2 /*return*/];
      }
    });
  });
}

test();

相關文章