Promise练习题 II

红灯3秒亮一次,绿灯1秒亮一次,黄灯2秒亮一次;如何使用Promise让三个灯不断交替重复亮灯?

// 定义3个亮灯函数
function red() {console.log('red');}
function green() {console.log('green');}
function yellow() {console.log('yellow');}
// 亮灯函数
let myLight = (timer, cb) => {
  // 返回一个Promise
  return new Promise((resolve) => {
    // 定时timer毫秒
    setTimeout(() => {
      // 定时结束后执行cb函数
      cb();
      // 并且更改当前Promise的状态为resolve
      resolve();
    }, timer);
  });
};
let myStep = () => {
  Promise.resolve().then(() => {
    // 因为myLight也是返回一个Promise
    // 执行之后传入的是red函数和3000ms的定时
    return myLight(3000, red);
  }).then(() => {
    // 这里的then承接的是上面then返回的Promise,在上面Promise执行完成之后
    // 才会进入这个then开始执行
    return myLight(2000, green);
  }).then(()=>{
    return myLight(1000, yellow);
  }).then(()=>{
    myStep();
  })
};
// 执行函数
myStep();

主要考察了链式调用和return Promise的情况,参考之前手写Promise的文章,每一个then()方法都是返回了一个新的Promise
Promise.then().then().then()这种多个链式调用的情况中,后面的then()会接受前面then()返回的resolve中的值,例如下面程序

let b = new Promise((resolve,reject) => {
  resolve(1)
  })
  .then((r) => { 
    console.log(r); 
    return 3
  })
  .then((r) => {
    console.log(r)
  })

最后输出的结果是


并且前面的then必须是resolve的时候才能传参

所以上面代码的流程就很清楚了,是返回的Promise延迟执行之后,后面的then()才会接受到resolve状态才能继续执行,从而实现的延迟调用。


请实现一个mergePromise函数,把传进去的数组按顺序先后执行,并且把返回的数据先后放到数组data中。

const timeout = ms => new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve();
    }, ms);
});
const ajax1 = () => timeout(2000).then(() => {
    console.log('1');
    return 1;
});
const ajax2 = () => timeout(1000).then(() => {
    console.log('2');
    return 2;
});
const ajax3 = () => timeout(2000).then(() => {
    console.log('3');
    return 3;
});
const mergePromise = ajaxArray => {
    // 在这里实现你的代码
};
mergePromise([ajax1, ajax2, ajax3]).then(data => {
    console.log('done');
    console.log(data); // data 为 [1, 2, 3]
});

// 要求分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]

可以看到这里最后的结果是通过then传递的,传入的3个ajax也都是返回的Promise,可以参照上题说的then()的链式调用来传递ajax中的参数,都传入data数组中即可

const mergePromise = ajaxArray => {
  // 返回的结果
  let data = [];
  // 和上一题举例一样,需要一个直接是成功状态的Promise
  var sequence = Promise.resolve();
  ajaxArray.forEach(item => {
    // 遍历每个传入的Promise,并且使用then获取他们的参数
    sequence = sequence.then(item).then(res => {
      // 存入数组
      data.push(res);
      // 相当于then(){return data}这样数据能被下一个then接收
      return data;
    });
  });
  // 返回这个Promise
  return sequence;
};

其实整体逻辑和这个代码差不多



相当于

 Promise.resolve().then(ajax1).then(res => {
  data.push(res)
  return data
})

ajax1会随着遍历不断变动,data是一个公共外部数据,每次push都会添加元素,并且因为这个赋值给了sequence,那么就是这样

 Promise.resolve().then(ajax1).then(res => {
  // 处理ajax1
  data.push(res)
  return data
}).then(ajax2).then(res => {
  // 处理ajax2
  data.push(res)
  return data
}).then(ajax3).then(res => {
  // 处理ajax3
  data.push(res)
  return data
}).

最后then的return会被整体返回,然后被后面的then接受,这个data已经保存了所有ajax的结果了,之后获取就可以


你可能感兴趣的:(Promise练习题 II)