问题:执行如下代码打印顺序是什么
function newPromise_resolve() {
return new Promise((resolve,reject) => {
resolve(); //这里调resolve方法,则then方法会被调用
console.log('resolve里面的log');
})
}
newPromise_resolve().then(() => {
console.log('then方法');
});
打印顺序如下
resolve里面的log
then方法
解析(如果回答对了,可以跳过)
其实也没啥可解析的直接看简单实现的源码吧
class MyPromise {
constructor (handle) {
if (!isFunction(handle)) {
throw new Error('MyPromise must accept a function as a parameter')
}
// 添加状态
this._status = PENDING
// 添加状态
this._value = undefined
// 执行handle
try {
handle(this._resolve.bind(this), this._reject.bind(this))
} catch (err) {
this._reject(err)
}
}
// 添加resovle时执行的函数,此处只是做了两件事1改变状态2记录value
_resolve (val) {
if (this._status !== PENDING) return
this._status = FULFILLED
this._value = val
}
// 添加reject时执行的函数
_reject (err) {
if (this._status !== PENDING) return
this._status = REJECTED
this._value = err
}
//
then (onFulfilled, onRejected) {
const { _value, _status } = this
switch (_status) {
// 当状态为pending时,将then方法回调函数加入执行队列等待执行
case PENDING:
this._fulfilledQueues.push(onFulfilled)
this._rejectedQueues.push(onRejected)
break
// 当状态已经改变时,立即执行对应的回调函数
case FULFILLED:
onFulfilled(_value)
break
case REJECTED:
onRejected(_value)
break
}
// 返回一个新的Promise对象
return new MyPromise((onFulfilledNext, onRejectedNext) => {
})
}
}
类koa事件模型
import request, { extend } from 'umi-request';
request.use(async (ctx, next) => {
console.log('a1');
await next();
console.log('a2');
});
request.use(async (ctx, next) => {
console.log('b1');
await next();
console.log('b2');
});
const data = await request('/api/v1/a');
执行顺序如下:
a1 -> b1 -> response -> b2 -> a2
简单源码实现
// 简化 koa-compose 源码下的 compose 方法
function compose(middleware) {
return function (context, next) {
return dispatch(0)
function dispatch(i) {
let fn = middleware[i]
if (i === middleware.length) fn = next
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}
class App {
constructor() {
// 定义中间件数组
this.middleware = [];
}
use(fn) {
if (fn && typeof fn !== "function") throw new Error('入参必须是函数');
// 入参 fn 都传入到 middleware 中间件数组中
this.middleware.push(fn);
}
listen(...arg) {
/**
* 源码,this.callbakck() 作为请求处理函数,本处省略该过程
* const server = http.createServer(this.callback());
* return server.listen(...args);
*/
this.callback();
}
callback() {
const fn = compose(this.middleware);
return this.handleRequest(fn);
}
handleRequest(fnMiddleware) {
return fnMiddleware()
.then(() => { console.log('over'); })
.catch((err) => { console.log(err); });
}
}
简要描述为 在 调用use的时候把中间件放到middleware数组中
在调用callback时 通过调用compose返回 dispatch外层函数, context会一直保留,每次调用next相当于调用了dispatch(i)函数,每次i都会加1,也就是会调用下一个next函数