We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
这个文章,展现的是一个实现promise的思路,以及如何发现和处理问题的情境。
如果我们想要自己实现一个简单的Promise,那现有规范规定的Promise肯定是我们最好的参照。
Promise
我们先看下Promise怎么使用:
var promise1 = new Promise(function(resolve, reject){ // 成功后的TODO resolve(value); // 失败后的TODO reject(err); })
来看下返回的promise1是什么
promise1
再进行一些具体操作
var promise1 = new Promise(function(resolve, reject) { resolve('zqz') }) promise1.then(function(result) { console.log(result) }).catch(function(err){ console.log(err) }) // => 'zqz'
var promise1 = new Promise(function(resolve, reject) { reject('出现异常') }) promise1.then(function(result) { console.log(result) }).catch(function(err){ console.log(err) }) // => '出现异常'
从Promise的 使用方式上 和 实例 可以看到哪些东西:
reject
resolve
then
catch
PromiseStatus
PromiseValue
pending
fulfilled
rejected
根据上面的分析情况,我们先简单的来构造一个雏形。
function Promise(fn) { this.PromiseStatus = 'pending'; this.PromiseValue = ''; this.resolvedCb = []; this.rejectedCb = []; var self = this; var resolve = function (result) { // 判断状态 if (self.PromiseStatus === 'pending') { self.PromiseStatus = 'resolved'; self.PromiseValue = result; // resolvedCb 队列依次执行 for (var i = 0;i < self.resolvedCb.length; i++) { self.resolvedCb[i](result) } } } var reject = function (err) { // 判断状态 if (self.PromiseStatus === 'pending') { self.PromiseStatus = 'rejected'; self.PromiseValue = err; // rejectedCb 队列依次执行 for (var i = 0;i < self.rejectedCb.length; i++) { self.rejectedCb[i](result) } } } // 错误处理 -> rejected try { fn(resolve, reject) } catch(e) { reject(e) } }
当然这还不够,因为重要的两个功能then和catch还没有实现。
分析下then的使用
promise1.then(function(value){ // todo return value; }) .then(function(value1){ // todo return value1; }) .then(function(value2){ // todo return value2; })
return
根据Promise返回的实例,我们可看出来then是挂载在 Promise 的原型链上。
我们先实现一个大体的框架:
Promise.prototype.then = function (handleSuccess, handleFail) { var self = this; var PromiseStatus = this.PromiseStatus; if(typeof handleSuccess === 'function') { handleSuccess = handleSuccess; } else { handleSuccess = function (result) {} } if(typeof handleFail === 'function') { handleFail = handleFail; } else { handleFail = function (err) {} } if(PromiseStatus === 'pending') { return new Promise(function(resolve, reject) { self.resolvedCb.push(handleSuccess); self.rejectedCb.push(handleFail); }) } if(PromiseStatus === 'resolved') { return new Promise(function(resolve, reject) { var result = handleSuccess(self.PromiseValue); resolve(result); }) } if(PromiseStatus === 'rejected') { return new Promise(function(resolve, reject) { var result = handleFail(self.PromiseValue); reject(result); }) } }
我们先用一下,看下是否符合期望
方式一(无异步操作):
function promise1() { return new Promise(function(resolve, reject){ console.log('执行promise1') resolve('zqz'); }) } promise1().then(function(result){ console.log('执行1', 'result:'+result) return result + '11'; }) .then(function(result){ console.log('执行2', 'result:'+result) return result + '22'; }) // => 执行promise1 // => 执行1 result:zqz // => 执行2 result:zqz11 // => Promise {PromiseStatus: "resolved", PromiseValue: "zqz1122", resolvedCb: Array(0), rejectedCb: Array(0)}
这样使用没有问题!
方式二(有异步操作):
function promise1() { return new Promise(function(resolve, reject){ // 异步操作 setTimeout(function(){ console.log('执行promise1') resolve('zqz'); },1000) }) } promise1().then(function(result){ console.log('执行1', 'result:'+result) return result + '11'; }) .then(function(result){ console.log('执行2', 'result:'+result) return result + '22'; }) // => 执行promise1 // => 执行1 result:zqz
一旦出现异步操作,就有问题!很明显,Promise的主要作用就是控制异步操作的执行顺序。
肯定是哪里有问题,我们来分析一下,异步的时候 有哪些 不同
在来看下我们在pending时候的处理
... // 异步时 if(PromiseStatus === 'pending') { return new Promise(function(resolve, reject) { // 这里只是将函数塞入队列,然后就没有然后来。。。这是有问题的 self.resolvedCb.push(handleSuccess); self.rejectedCb.push(handleFail); }) } ...
这时候我们的两个数组:resolvedCb和rejectedCb就发挥作用了,由于我们不知道异步什么时候结束,但是我们可以根据他们定义的先后顺序注入到 队列 中,然后根据 顺序 依次执行,这样也就保证了异步操作的执行顺序。
resolvedCb
rejectedCb
队列
顺序
if(PromiseStatus === 'pending') { return new Promise(function(resolve, reject) { // 一个个的塞入队列 self.resolvedCb.push(function(result) { var res = handleSuccess(self.PromiseValue); resolve(res); }) self.rejectedCb.push(function(err) { var er = handleFail(self.PromiseValue); reject(er); }) }) }
这时候我们用多个异步操作来测试一下
异步操作
function async1() { return new Promise(function(resolve, reject){ // 异步操作 setTimeout(function(){ console.log('执行async1') resolve('zqz1'); },3000) }) } function async2() { return new Promise(function(resolve, reject){ // 异步操作 setTimeout(function(){ console.log('执行async2') resolve('zqz2'); },1000) }) } function async3() { return new Promise(function(resolve, reject){ // 异步操作 setTimeout(function(){ console.log('执行async3') resolve('zqz3'); },2000) }) } // return 一个新的promise async1().then(function(result){ console.log('result = ' + result) return async2(); }).then(function(result){ console.log('result = ' + result) return async3(); }).then(function(result){ console.log('result = ' + result) return result; }) // => Promise {PromiseStatus: "pending", PromiseValue: "", resolvedCb: Array(0), rejectedCb: Array(0)} // => 执行async1 // => result = zqz1 // => result = [object Object] // => result = [object Object] // => 执行async2 // => 执行async3
这里有两个问题:
我们再来分析下,着重看下下面这块代码
... if(PromiseStatus === 'pending') { return new Promise(function(resolve, reject) { self.resolvedCb.push(function(result) { // 这里返回的res有可能是promise,但是我们没有做处理 var res = handleSuccess(self.PromiseValue); resolve(res); }) self.rejectedCb.push(function(err) { // 这里返回的res有可能是promise,但是我们没有做处理 var er = handleFail(self.PromiseValue); reject(er); }) }) } ...
因为我们返回的是Promise,由于我们没有做处理,导致无法正确的获取到值。
... if(PromiseStatus === 'pending') { return new Promise(function(resolve, reject) { self.resolvedCb.push(function(result) { var res = handleSuccess(self.PromiseValue); if (res instanceof Promise) { res.then(resolve, reject); } else { resolve(res); } }) self.rejectedCb.push(function(err) { var er = handleFail(self.PromiseValue); if (er instanceof Promise) { er.then(resolve, reject); } else { reject(er); } }) }) } ...
如果返回的是一个Promise,就继续塞入到then里面。
在执行一下:
async1().then(function(result){ console.log('result = ' + result) return async2(); }).then(function(result){ console.log('result = ' + result) return async3(); }).then(function(result){ console.log('result = ' + result) return result; }) // => Promise {PromiseStatus: "pending", PromiseValue: "", resolvedCb: Array(0), rejectedCb: Array(0)} // => 执行async1 // => result = zqz1 // => 执行async2 // => result = zqz2 // => 执行async3 // => result = zqz3
最后一个简单完整的 then:
Promise.prototype.then = function (handleSuccess, handleFail) { var self = this; var PromiseStatus = this.PromiseStatus; if(typeof handleSuccess === 'function') { handleSuccess = handleSuccess; } else { handleSuccess = function (result) {} } if(typeof handleFail === 'function') { handleFail = handleFail; } else { handleFail = function (err) {} } if(PromiseStatus === 'pending') { return new Promise(function(resolve, reject) { self.resolvedCb.push(function(result) { var res = handleSuccess(self.PromiseValue); if (res instanceof Promise) { res.then(resolve, reject); } else { resolve(er); } }) self.rejectedCb.push(function(err) { var er = handleFail(self.PromiseValue); if (er instanceof Promise) { er.then(resolve, reject); } else { reject(er); } }) }) } if(PromiseStatus === 'resolved') { return new Promise(function(resolve, reject) { var result = handleSuccess(self.PromiseValue); resolve(result); }) } if(PromiseStatus === 'rejected') { return new Promise(function(resolve, reject) { var result = handleFail(self.PromiseValue); reject(result); }) } }
参考
The text was updated successfully, but these errors were encountered:
看完你的promise,感觉好牛逼呀! 简单大气,自己手敲一遍学习学习。
Sorry, something went wrong.
@wcx521 谢谢您的赞赏,互相学习!
No branches or pull requests
写在前面
这个文章,展现的是一个实现promise的思路,以及如何发现和处理问题的情境。
从现有的Promise分析
如果我们想要自己实现一个简单的
Promise
,那现有规范规定的Promise
肯定是我们最好的参照。我们先看下
Promise
怎么使用:来看下返回的
promise1
是什么再进行一些具体操作
从Promise的 使用方式上 和 实例 可以看到哪些东西:
reject
和resolve
reject
和resolve
都有一个参数, 参数类型不限定then
和catch
,同时then可以有多个,所以需要一个回掉函数队列PromiseStatus
和PromiseValue
pending
,fulfilled
,rejected
根据上面的分析情况,我们先简单的来构造一个雏形。
当然这还不够,因为重要的两个功能
then
和catch
还没有实现。从现有的 then 分析
分析下
then
的使用return
的值 直接作为下个then
中匿名函数的入参根据Promise返回的实例,我们可看出来
then
是挂载在 Promise 的原型链上。我们先实现一个大体的框架:
我们先用一下,看下是否符合期望
方式一(无异步操作):
这样使用没有问题!
方式二(有异步操作):
一旦出现异步操作,就有问题!很明显,Promise的主要作用就是控制异步操作的执行顺序。
肯定是哪里有问题,我们来分析一下,异步的时候 有哪些 不同
PromiseStatus
是pending
状态在来看下我们在
pending
时候的处理这时候我们的两个数组:
resolvedCb
和rejectedCb
就发挥作用了,由于我们不知道异步什么时候结束,但是我们可以根据他们定义的先后顺序注入到队列
中,然后根据顺序
依次执行,这样也就保证了异步操作的执行顺序。这时候我们用多个
异步操作
来测试一下这里有两个问题:
我们再来分析下,着重看下下面这块代码
因为我们返回的是Promise,由于我们没有做处理,导致无法正确的获取到值。
如果返回的是一个Promise,就继续塞入到then里面。
在执行一下:
最后一个简单完整的 then:
参考
The text was updated successfully, but these errors were encountered: