关于javascript:简述函数式编程与JS异步编程手写Promise

9次阅读

共计 5318 个字符,预计需要花费 14 分钟才能阅读完成。

简答题
一、
1.javascript 为什么是单线程?

 与 javascript 的设计初衷无关,最早 javascript 是运行在浏览器中的脚本语言,目标是为了实现页面上的动静交互,实现页面的外围是 dom 操作,所以决定了 javascript 是单线程,否则会呈现线程同步的问题:
比方多个线程同时操作一个 dom 元素,这时浏览器不晓得要以谁的操作为准,造成代码执行程序凌乱
javascript 是单线程也就意味着浏览器有多个工作的时候要排队顺次进行,一个一个实现,这种模式的长处是比拟平安。毛病是如果咱们遇到一个特地耗费工夫的工作,那么前面的工作就会始终等着这个工作的实现,这样会造成页面卡死的状况,会造成阻塞。javascript 语言无奈解决大量的耗时工作,为了解决这个问题,javascript 讲执行工作分成了两种模式:同步模式和异步模式 

2. 同步模式

 同步模式指的是咱们的 javascript 代码要顺次执行,前面的代码要期待前一句代码执行实现能力执行,排队执行,javascript 代码大多数是以同步模式进行执行的 

3. 异步模式

 异步模式指的是咱们的 javascript 代码不会期待后面的代码执行结束才开始执行。咱们将执行的代码放入到调用栈中执行,如果是同步的间接执行,如果是异步的则放入音讯队列中期待执行,等到所有的代码执行结束,咱们的 event loop 就上场了,它会监听调用栈和音讯队列中的工作,当调用栈中所有的工作完结当前,它会从音讯队列中顺次取出回调函数压入到调用栈,开始执行,直到整个循环完结 

4.Event Loop

 主线程从音讯队列中读取事件,这个过程是循环不断的,所以整个的这种运行机制称为 Event Loop(事件循环),Event Loop 是 javascript 的执行机制 

5. 音讯队列

 音讯队列是临时寄存异步工作的中央,咱们的异步代码会寄存到音讯队列中,等到同步代码执行结束当前,event loop 会从音讯队列中顺次取出异步工作放到调用栈中再次执行。

6. 宏工作, 微工作

 宏工作: 以后调用栈中执行的代码成为宏工作,包含 主代码快,定时器
微工作: 宏工作执行完, 在下一个宏工作开始之前须要执行的工作, 能够了解为回调函数

运行机制:在执行栈中执行一个宏工作
执行过程中遇到微工作,将微工作增加到音讯队列中
以后宏工作执行结束, 立刻执行微工作队列中的工作
微工作执行结束后,把下一个宏工作放到音讯队列中,通过 eventloop 放到调用栈中执行。

代码题
一、

new Promise((resolve, reject) => {
  var a = 'hello'
  resolve(a)
}).then(value=> {
  var b = 'lagou'
  return value + b
}).then(value=> {
  var c = 'I❤U'
  console.log(value + c)
})

二、

 练习 1:let isLastInStock = function(cars) {
    // 获取最初一条数据
    let last = cars => cars.pop()
    // 获取最初一条数据 in_stock 属性值
    let getValue = last => last.in_stock
    return fp.flowRight(value, last)
}

练习 2:let isFirstName = function(cars) {
    // 获取第一条数据
    // 获取第一条数据 name 属性值
     return fp.flowRight(fp.prop('name'), fp.first)
}

练习 3:let _average = xs => {return fp.reduce(fp.add, 0, xs)
}
let averageDollarValue = cars => {return _average(fp.flowRight(fp.map(fp.prop('dollar_value')))(cars))
}

练习 4:let _underscore = fp.replace(/\s+/g, '_')
let arr = fp.flowRight(fp.map(fp.prop('name')))(cars)
let sanitizeNames = arr => {return fp.flowRight(fp.map(fp.flowRight(_underscore, fp.toLower)))(arr)
}

三、

//support.js
class Container {static of(value) {return new Container(value)
      }
      construtor(value) {this._value = value}
      map(fn) {return Container.of(fn(this._value))
      }
}

class MayBe {static of (value) {return new MayBe(value)
      }

     constructor (value) {this._value = value}

      map (fn) {return this.isNothing() ? MayBe.of(null) : MayBe.of(fn(this._value))
      }

      isNothing () {return this._value === null || this._value === undefined}
}

module.exports = {MayBe, Container}

练习 1:const fp = require('lodash/fp')
const {MayBe, Container} = require('./support')

let maybe= MayBe.of([5,6,1])
let ex1 = () => {return maybe.map(arr => fp.flowRight(fp.map(fp.add(1)))(arr))
}

练习 2:let ex2 = () => {return xs.map(arr => fp.first(arr))
}

练习 3:let ex3 = () => {return safeProp('name', user).map(x => fp.first(x))
}

练习 4:let ex4 = (n) => {return MayBe.of(n).map(n => parseInt(n))
}

四、

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class Promise {constructor(executor) {
    // 状态初始化为 pending
    this.status = PENDING
    // 胜利传参
    this.value = undefined
    // 失败起因
    this.reason = undefined
    // 存储胜利的回调函数
    this.successCallbacks = []
    // 存储失败的回调函数
    this.failCallbacks = []
    // 胜利
    let resolve = (value) => {if(this.status == PENDING) {
            this.status = FULFILLED
               this.value = value
            while (this.successCallbacks.length) this.successCallbacks.shift()()
          }
    }
    // 失败
    let reject = (reason) =>{if(this.status == PENDING) {
                this.status = REJECTED
             this.reason = reason
             while (this.failCallbacks.length)  this.failCallbacks.shift()()
          }
    }
    try {executor(resolve, reject)
    } catch(err) {reject(err)
    }
  }

  then(successCallback, failCallback) {
    // 参数可有能够无
    successCallback = successCallback ? successCallback : value => value
    failCallback = failCallback ? failCallback : reason => {throw reason}
    let promise2 = new Promise((resolve, reject)=>{if(this.status == FULFILLED) {setTimeout(()=>{ // 异步让 promise2 先创立
                  try {let x = successCallback(this.value)
                    // 判断 x 的值是一般值还是 Promise 对象
                    // 一般值 间接调用 reslove
                    // 若是 Promise 对象,查看 Promise 对象返回的接口
                    // 再依据后果,决定调用 resolve 还是 reject
                    resolvePromise(promise2, x, resolve, reject)
                 } catch(err) {reject(err)
                  }
               }, 0)


          } else if(this.status == REJECTED) {setTimeout(()=>{ // 异步让 promise2 先创立
                  try {let x = failCallback(this.reason)
                    // 判断 x 的值是一般值还是 Promise 对象
                    // 一般值 间接调用 reslove
                    // 若是 Promise 对象,查看 Promise 对象返回的接口
                    // 再依据后果,决定调用 resolve 还是 reject
                    resolvePromise(promise2, x, resolve, reject)
                 } catch(err) {reject(err)
                  }

               }, 0)
          } else {
            // 存储胜利的回调函数
            this.successCallbacks.push(()=> {setTimeout(()=>{ // 异步让 promise2 先创立
                        try {let x = successCallback(this.value)
                          // 判断 x 的值是一般值还是 Promise 对象
                          // 一般值 间接调用 reslove
                          // 若是 Promise 对象,查看 Promise 对象返回的接口
                          // 再依据后果,决定调用 resolve 还是 reject
                          resolvePromise(promise2, x, resolve, reject)
                       } catch(err) {reject(err)
                    }
             }, 0)
        })
        // 存储失败的回调函数
    this.failCallbacks.push(()=> {setTimeout(()=>{ // 异步让 promise2 先创立
        try {let x = failCallback(this.reason)
          // 判断 x 的值是一般值还是 Promise 对象
          // 一般值 间接调用 reslove
          // 若是 Promise 对象,查看 Promise 对象返回的接口
          // 再依据后果,决定调用 resolve 还是 reject
          resolvePromise(promise2, x, resolve, reject)
       } catch(err) {reject(err)
        }

     }, 0)
    })
  }
})
   return promise2
  }

  finally (callback) {
    return this.then(value => {return MyPromise.resolve(callback()).then(() => value);
    }, reason => {return MyPromise.resolve(callback()).then(() => { throw reason})
    })
  }

  catch (failCallback) {return this.then(undefined, failCallback)
  }

  static all (array) {let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {function addData (key, value) {result[key] = value;
    index++;
    if (index === array.length) {resolve(result);
    }
  }
  for (let i = 0; i < array.length; i++) {let current = array[i];
    if (current instanceof MyPromise) {
      // promise 对象
      current.then(value => addData(i, value), reason => reject(reason))
    }else {
      // 一般值
      addData(i, array[i]);
    }
  }
})
  }

  static resolve (value) {if (value instanceof MyPromise) return value;
        return new MyPromise(resolve => resolve(value));
       }
}

function resolvePromise (promise2, x, resolve, reject) {if(promise2 === x) {return reject(new TypeError('返回了雷同的 Promise 对象'))
      }
      if(x instanceof Promise) {
        //promise 对象
        x.then(resolve, reject)
      } else {
    // 一般值
    resolve(x)
  }
}
module.exports = Promise
正文完
 0