hookex
4/11/2020 - 5:26 AM

Promise

Promise

function promiseFinally(promise: Promise<any>) {
  return new Promise(resolve => {
    promise.then(resolve).catch(resolve);
  })
}


promiseFinally(new Promise(resolve => resolve(1))).then(console.log)
promiseFinally(new Promise((_, reject) => reject(2))).then(console.log)
function promiseCreator(num) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(num + 2);
    });
  });
}

function promiseQueue(createors) {
  let data = 0;

  return new Promise(resolve => {
    function helper(createors) {
      if (createors.length) {
        const currentPromise = createors.shift();
        currentPromise(data).then(_data => {
          data = _data;
          helper(createors);
        });
      } else {
        resolve(data);
      }
    }

    helper(createors);
  });
}

promiseQueue([
  promiseCreator,
  promiseCreator,
  promiseCreator,
  promiseCreator
]).then(console.log);
class Scheduler {
  private queue = [];
  private running = [];
  constructor(public maxCount: number) {}

  add(promiseFunc: Function): Promise<any> {
    this.queue.push(promiseFunc);
    return this.tick();
  }

  tick() {
    const { running, maxCount, queue } = this;
    if (running.length < maxCount && queue.length) {
      const task = queue.shift();

      const promise = task().then(_ => {
        this.running.splice(this.running.indexOf(promise), 1);
      });
      this.running.push(promise);

      return promise;
    }

    // todo: 这里返回好像不对
    return Promise.race(running).then(_ => this.tick());
  }
}

const timeout = (time: number) =>
  new Promise(resove => {
    setTimeout(resove, time);
  });

const scheduler = new Scheduler(1);

scheduler.add(_ => timeout(1000)).then(_ => console.log(1));
scheduler.add(_ => timeout(1000)).then(_ => console.log(2));
scheduler.add(_ => timeout(1000)).then(_ => console.log(3));
scheduler.add(_ => timeout(1000)).then(_ => console.log(4));
scheduler.add(_ => timeout(1000)).then(_ => console.log(5));
scheduler.add(_ => timeout(1000)).then(_ => console.log(6));
scheduler.add(_ => timeout(1000)).then(_ => console.log(7));
function memo(promiseFunc: Function) {
  const cache = {};

  return function(...args): Promise<any> {
    const key = args.join();

    if (cache[key]) {
      return cache[key];
    }

    return (cache[key] = promiseFunc.apply(this, args));
  };
}

function fetch(url: string) {
  return new Promise((resolve, reject) => {
    setTimeout(_ => {
      console.log("timeout");
      resolve({ url });
    }, 1000);
  });
}

const memoFetch = memo(fetch);

memoFetch("baidu").then(data => console.log(data));
memoFetch("baidu").then(data => console.log(data));
memoFetch("baidu").then(data => console.log(data));
memoFetch("google").then(data => console.log(data));

setTimeout(() => {
  memoFetch("google").then(data => console.log(data));
}, 2000);

/**
output:

timeout 
Object {url: "baidu"}
Object {url: "baidu"}
Object {url: "baidu"}
timeout 
Object {url: "google"}

Object {url: "google"}
*/


// 方式2


const cb = (function() {
  let result = null;
  let resolves = [];

  function temp() {
    setTimeout(function() {
      result = "success";
      console.log(result);
      resolves.forEach(resolve => resolve());
    }, 1000);
  }

  return function(resolve) {
    if (result) {
      return result;
    } else {
      if (resolves.length === 0) {
        temp();
      }
      resolves.push(resolve);
    }
  };
})();

function fetchData() {
  return new Promise(resolve => {
    cb(resolve);
  });
}

for (let i = 0; i < 10; i++) {
  fetchData().then(res => {
    console.log("then", res);
  });
}
var p1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "one");
});
var p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, "two");
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, "three");
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(resolve, 4000, "four");
});
var p5 = new Promise((resolve, reject) => {
  reject("reject");
});

function promiseAll(promises: Promise<any>[]): Promise<any> {
  let count = promises.length;
  const result = new Array(promises.length);
  let done = 0;

  return new Promise((resolve, reject) => {
    promises.forEach((p, i) => {
      p.then(data => {
        result[i] = data;
        done++;
        console.log(done, count);

        if (done === count) {
          resolve(result);
        }
      }).catch(err => {
        reject(err);
      });
    });
  });
}

promiseAll([p1, p2, p3, p4, p5])
  .then(dataList => console.log(dataList))
  .catch(err => console.log(err));

promiseAll([p1, p2, p3, p4])
  .then(dataList => console.log(dataList))
  .catch(err => console.log(err));
var p1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "one");
});
var p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, "two");
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, "three");
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(resolve, 4000, "four");
});

function promiseRace(promises: Promise<any>[]): Promise<any> {
  return new Promise(resolve => {
    promises.forEach((p, i) => {
      p.then(data => {
        resolve(data);
      });
    });
  });
}

promiseRace([p1, p2, p3, p4]).then(data => console.log(data));