1. 程式人生 > >非同步實現方式

非同步實現方式

方式一:回撥函式

  const step1 = (value, fn) => {
    setTimeout(() => {
      fn(value + 1);
    }, 3000);
  };

  const step2 = (value, fn) => {
    setTimeout(() => {
      fn(value + 2);
    }, 3000);
  }

  const step3 = (value, fn) => {
    setTimeout(() => {
      fn(value + 3);
    }, 3000);
  }

  const step = (value) => {
    step1(value, (value2) => {
      step2(value2, (value3) => {
        step3(value3, (value4) => {
          console.log(value4, 'value4');
        })
      })
    })
  }

  step(1); //7 "value4"

方式二:promise基本方式

  const step1 = (value) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(value + 1), 3000)
  })

  const step2 = (value) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(value + 2), 3000)
  })

  const step3 = (value) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(value + 3), 3000)
  })


  step1(1)
    .then(step2)
    .then(step3)
    .then((value) => {
      console.log(value, 'value');
    })
    .catch((err) => {
      console.log(err, 'err');
    }) 
  //7 "value"

方式三: generator基本方式

  const step1 = (value) => {
    setTimeout(() => {
      iter.next(value + 1);
    }, 3000)
  };

  const step2 = (value) => {
    setTimeout(() => {
      iter.next(value + 2);
    }, 3000)
  };

  const step3 = (value) => {
    setTimeout(() => {
      iter.next(value + 3);
    }, 3000)
  };

  function* generator(value) {
    try {
      const value1 = yield step1(value);
      const value2 = yield step2(value1);
      const value3 = yield step3(value2);
      console.log(value3, 'value3');
    } catch(err) {
      console.log(err, 'err');
    }
  }

  const iter = generator(1);
  iter.next(); //7 "value3"
  const step1 = (value) => {
    setTimeout(() => {
      iter.next(value + 1);
    }, 3000)
  };

  const step2 = (value) => {
    setTimeout(() => {
      iter.next(value + 2);
    }, 3000)
  };

  const step3 = (value) => {
    setTimeout(() => {
      iter.next(value + 3);
    }, 3000)
  };

  function* generator({steps, initial}) {
    let result = initial;
    for(let i = 0, len = steps.length; i < len; i++) {
      const step = steps[i];
      result = yield step(result);
    }
    console.log(result, 'result')
  }
  
  const param = {
    steps: [step1, step2, step3],
    initial: 1
  };

  const iter = generator(param);
  iter.next(); //7 "result"

方式四:Thunk的generator方式 

  const step1 = (value, callback) => {
    setTimeout(() => callback(value + 1), 3000);
  };

  const step2 = (value, callback) => {
    setTimeout(() => callback(value + 2), 3000);
  };

  const step3 = (value, callback) => {
    setTimeout(() => callback(value + 3), 3000);
  };

  const Thunk = (fn) => {
    return (...args) => {
      return (callback) => {
        return fn.call(this, ...args, callback);
      }
    }
  };

  const gen = function* (initial = 1) {
    const value1 = yield Thunk(step1)(initial);
    const value2 = yield Thunk(step2)(value1);
    const value3 = yield Thunk(step3)(value2);
    console.log(value3, 'value3');
  }

  //自動流程管理
  const run = (gen) => {
    const g = gen();
    const next = (data) => {
      const result = g.next(data);
      if (result.done) return;
      result.value(next);
    }
    next();
  }

  run(gen); //7 "value3"

方式五:基於Promise的自動執行

  const step1 = (value, callback) => {
    setTimeout(() => callback(value + 1), 3000);
  };

  const step2 = (value, callback) => {
    setTimeout(() => callback(value + 2), 3000);
  };

  const step3 = (value, callback) => {
    setTimeout(() => callback(value + 3), 3000);
  };

  const stepPromise = (fn) => {
    return (...args) => {
      return new Promise((resolve, reject) => {
        fn(...args, (value) => {
          resolve(value)
        })
      })
    }
  }

  const gen = function* (initial = 1) {
    const value1 = yield stepPromise(step1)(initial);
    const value2 = yield stepPromise(step2)(value1);
    const value3 = yield stepPromise(step3)(value2);
    console.log(value3, 'value3');
  }

  //自動管理流程
  const run = (gen) => {
    const g = gen();
    const next = (data) => {
      const result = g.next(data);
      if (result.done) return;
      result.value.then((data) => {
        next(data);
      });
    }
    next();
  }

  run(gen); //7 "value3"

方式六:async函式 方式

  const step1 = (value) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(value + 1), 3000);
    })
  };

  const step2 = (value) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(value + 2), 3000);
    })
  };

  const step3 = (value) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(value + 3), 3000);
    })
  };

  const asyncFn = async (initial = 1) => {
    const value1 = await step1(initial);
    const value2 = await step2(value1);
    const value3 = await step3(value2);
    return value3;
  }

  asyncFn().then(result => console.log(result, 'result')); //7 'result'