promise相关 | 青训营笔记

77 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第7天

什么是promise

所谓Promise,字面上可以理解为“承诺”,就是说A调用B,B返回一个“承诺”给A,然后A就可以在写计划的时候这么写:当B返回结果给我的时候,A执行方案S1,反之如果B因为什么原因没有给到A想要的结果,那么A执行应急方案S2,这样一来,所有的潜在风险都在A的可控范围之内了。

Promise规范如下:

  • 一个promise可能有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)
  • 一个promise的状态只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换
  • promise必须实现then方法(可以说,then就是promise的核心),而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致
  • then方法接受两个参数,第一个参数是成功时的回调,在promise由“等待”态转换到“完成”态时调用,另一个是失败时的回调,在promise由“等待”态转换到“拒绝”态时调用。同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。

peomise实现

/* promise的简单实现 */
class myPromise{
    constructor (process) {
        this.status = 'pending';
        this.msg = '';
        process(this.resolve.bind(this), this.reject.bind(this));
        return this;
    }
    resolve (val) {
        this.status = 'resolved';
        this.msg = val;
    }
    reject (err) {
        this.status = 'rejected';
        this.msg = err;
    }
    then (resolve, reject) {
        if(this.status == 'resolved')
            resolve(this.msg);
        if(this.status == 'rejected')
            reject(this.msg);
    }
}

//Test
var my_promise = new myPromise(function(resolve, reject) {
    resolve('OK');
});
my_promise.then(function(val) {
    console.log(`success: ${val}`);
}, function(err){
    console.log(`failed: ${err}`);
}); //输出success: OK

promise应用

按照要求实现 mergePromise 函数,把传进去的函数数组按顺序先后执行,并且把返回的数据先后放到数组 data 中。 编写 JavaScript 代码,跑通如下测试用例

const timeout = (ms) =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, ms);
  });

const ajaxA = () =>
  timeout(2000).then(() => {
    console.log("A");
    return A;
  });

const ajaxB = () =>
  timeout(1000).then(() => {
    console.log("B");
    return B;
  });

const ajaxC = () =>
  timeout(2000).then(() => {
    console.log("C");
    return C;
  });

const mergePromise = (fetchArray) => {
  // 在这里实现你的代码
};

//测试用例
mergePromise([fakeFetchWeather(), fakeFetchWeather(), fakeFetchWeather()]).then(
  (data) => {
    console.log("done");
    console.log(data); // data 为 [A, B, C]
  }
);

// 要求分别输出
// A
// B
// C
// done
// [A, B, C]

首先mergePromise里面需要有then方法,所以在mergePromise中必须return一个new promise, 然后根据传入的promise数组进行顺序执行,并只有执行完才能执行下一个;因此有如下代码

const mergePromise = async (fetchArray) => {
  //在这里实现你的代码
  return new Promise((resolve,reject)=>{
    let promise = Promise.resolve()
    let data = fetchArray.reduce((ans,item)=>{
      promise = promise.then(item).then(res=>{
        ans.push(res)
      })
      return ans
    },[])
    return promise.then(()=>resolve(data))
  })
};

promise和async await的区别

  1. Promise的出现解决了传统callback函数导致的“地域回调”问题,但它的语法导致了它向纵向发展行成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async await代码看起来会简洁些,使得异步代码看起来像同步代码,await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。
  2. async await与Promise一样,是非阻塞的。
  3. async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函数。