promise

手写一些 promise 的 pollyfill 以及执行顺序相关(执行顺序头条面试问到过)。

  • 相关 pollyfill
    • promise.all
    • promise.finally
  • 执行顺序
    • 并行执行 promise 发送请求返回结果
    • 串行执行 promise 发送请求返回结果
    • 执行 n 次 promise 发送请求返回结果

手写 pollyfill

promise.all

写一个 promise.all 的 pollyfill

思路

很简单,就是构建一个 promise,都执行完了返回结果

function all(list) {
  let count = 0;
  let resValues = [];
  return new Promise((resolve, reject) => {
    list.forEach((p, i) => {
      Promise.resolve(p).then(
        res => {
          count++;
          resValues[i] = res;
          if (count === list.length) {
            resolve(resValues);
          }
        },
        err => {
          reject(err);
        }
      );
    });
  });
}
var p1 = Promise.resolve(1),
  p2 = Promise.resolve(2),
  p3 = Promise.resolve(3);
all([p1, p2, p3]).then(function(value) {
  console.log(value);
});

promise.finally

用 p.resolve 是希望 cb 如果是个 promise,需要等他执行完再执行。

Promise.prototype.finally = function(cb) {
  const p = this.constructor;
  return this.then(
    value =>
      p.resolve(cb()).then(() => {
        return value;
      }),
    error =>
      p.resolve(cb()).then(() => {
        throw error;
      })
  );
};

执行顺序

面试头条问到过的题目,提供一个 getData(url)的 promise 方法,可以获取请求数据。按照要求构造方法返回 promise。

// 提供的帮助函数
function getData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(url);
    }, 1000);
  });
}

并行执行 promise 发送请求返回结果

输入是 url 的数组,输出是一个 promise,要求并行发送请求。

思路

直接用 promise.all 就能实现

function parallelFetch(urls) {
  const promiseArr = [];
  urls.forEach(u => {
    promiseArr.push(getData(u));
  });
  return Promise.all(promiseArr);
}

串行执行 promise 发送请求返回结果

输入是 url 的数组,输出是一个 promise,要求串行发送请求。

思路

这一题我没能答出来,串行返回 promise 没能想到用 reduce 来做,可惜,想到了就很简单了,每次 then 都能将 getData 执行完。

function serialFetch(urls) {
  return urls.reduce((p, u) => {
    return p.then(data => {
      console.log(data);
      return getData(u);
    });
  }, Promise.resolve());
}

执行 n 次 promise 发送请求返回结果

输入是 url 以及次数 n,输出是一个 promise,要求成功了就返回结果,失败了就重试 n 次。

思路

思路很简单,成功了就返回结果,失败了就进行检查,如果少于 n 次就递归,

function tryFetch(url, n) {
  return getData(url).then(
    data => {
      return data;
    },
    () => {
      if (n > 1) {
        return tryFetch(url, n - 1);
      }
    }
  );
}

// test case
let n = 0;
function getData(url) {
  n++;
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (n > 4) {
        console.log("成功");
        resolve("success");
      } else {
        console.log("失败");
        reject("error");
      }
    }, 1000);
  });
}
tryFetch("123", 3).then(
  data => {
    console.log(data);
  },
  error => {
    console.log(error);
  }
);

promise 的面试题还是挺考验编程能力的,可以着重准备下。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 981909093@qq.com

文章标题:promise

文章字数:631

本文作者:泽鹿

发布时间:2019-08-29, 11:43:55

最后更新:2019-09-02, 11:43:24

原始链接:http://panyifei.github.io/2019/08/29/前端面试/代码/异步/promise/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏