Promise 规范

2020-05-27  本文已影响0人  monkeyfly36

ES6中采用了 Promise/A+ 规范
https://www.imooc.com/learn/949

Promise标准解读,记住两点:
1.一个promise的当前状态只能是pending、fulfilled和rejected三种之一。状态改变只能是pending到fulfilled或者pending到rejected。状态改变不可逆。
(2) promise的then方法接收两个可选参数,表示该promise状态改变时的回调(promise.then(onFulfilled, onRejected))。then方法返回一个promise,then方法可以被同一个 promise 调用多次。
注:Promise/A+并未规范race、all、catch方法,这些是ES6自己规范的。

Promise原理:采用了观察者模式

function Promise(fn) {
    var value = null
    var callbacks = []  //callbacks为数组,因为可能同时有很多个回调

    this.then = function (onFulfilled) {
        callbacks.push(onFulfilled)
    }

    function resolve(value) {
        callbacks.forEach(function (callback) {
            callback(value)
        })
    }

    fn(resolve)
}

题:
1.红灯三秒亮一次,绿灯一秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?(用Promise实现)三个亮灯函数已经存在。

function red() {
  console.log('red')
}
function green() {
  console.log('green')
}
function yellow() {
  console.log('yellow')
}

var light = function (timmer, func) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      func()
      resolve()
    }, timmer)
  })
}

var step = function () {
  Promise.resolve().then(function () {
    return light(3000, red)
  }).then(function () {
    return light(1000, green)
  }).then(function () {
    return light(2000, yellow)
  }).then(function () {
    step()
  })
}

2.实现 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]
})

3.打印顺序

const first = () => (new Promise((resolve, reject) => {
    console.log(3)
    let p = new Promise((resolve, reject) => {
        console.log(7)
        setTimeout(() => {
            console.log(5)
            resolve(6)
        }, 0)
        resolve(1)
    })
    resolve(2)
    p.then((arg) => {
        console.log(arg);
    })

}))

first().then((arg) => {
    console.log(arg)
})
console.log(4)
// 3,7,4,1,2,5

注:常见异步方法:
1.回调函数
2.事件监听
3.发布/订阅
4.Promise对象

上一篇下一篇

猜你喜欢

热点阅读