class MyPromise {
constructor(func) {
this.task = [];
this.errTask=undefined;
this.ball = null;
this.status=undefined;
setTimeout(() => {
func(this.resolve.bind(this), this.reject.bind(this))
}, 0)
}
resolve(obj) {
if(this.status) return;
this.status="resolved";
this.ball = obj;
console.log(this.task.length)
this.task.forEach((func) => {
this.ball = func(this.ball)
})
}
reject(obj) {
if(this.status) return;
this.status="rejected";
this.ball=obj;
if(this.errTask)this.errTask(obj)
}
then(func,errFunc) {
this.task.push(func);
if(!this.errTask && errFunc) this.errTask=errFunc;
return this;
}
}
function fff(resolve, reject) {
reject("kkk err")
//resolve({ name: "kim" })
}
// test
var m = new MyPromise(fff)
var num=1;
m.then((obj) => { console.log(obj);num++; return { age: num } },(obj)=>console.log(obj))
Este MyPromise implementa as funções básicas de resolução e rejeição.Depois que o estado de resolução e rejeição é definido, ele não pode ser alterado.
Aqui precisamos explicar o setTimeout no construtor:
Em js, independentemente da situação do Worker, tudo é de thread único, mas o mecanismo js tem sua própria fila de tarefas. Durante a execução do programa js, algumas tarefas serão adicionadas à fila uma por uma e depois executadas em sequência. E setTimeout é realmente adicionar uma tarefa a essa fila com um certo atraso, mas adicioná-la à fila não significa que ela será executada imediatamente, mas terá que esperar até que a execução da tarefa anterior termine. Portanto, a tarefa com um atraso de zero segundos aqui aguardará a conclusão do programa atual (a tarefa mais frontal da fila) antes de executar. O programa atual chamou então para adicionar a função a ser executada na fila de tarefas do Promise, para que a resolução subsequente possa usar essas funções.