最终实现的Promise代码,详细过程情况文章最后的原文链接。
// 例1
function getUserId() {
return new Promise(function (resolve) {
// 异步请求
Y.io('/userid', {
on: {
success: function (id, res) {
resolve(JSON.parse(res).id);
}
}
});
});
}
function getUserMobileById(id) {
return new Promise(function (resolve) {
console.log('start to get user mobile by id:', id);
Y.io('/usermobile/' + id, {
on: {
success: function (i, o) {
resolve(JSON.parse(o).mobile);
}
}
});
});
}
getUserId().then(getUserMobileById).then(function (mobile) {
// do sth with mobile
});
//------------
function Promse(fn) {
var state = 'pending',
value = null,
deferreds = [];
this.then = function(onFulfilled, onRejected) {
return new Promse(function (resolve, reject) {
handle({
onFulfilled: onFulfilled || null,
onRejected: onRejected || null,
resolve: resolve,
reject: reject,
})
});
//resolve执行后,then添加的新回调都会立即执行
//处理即一个Promise后带多个then情况
// if (state == 'pending') {
// deferreds.push(onFulfilled);
// return this;
// }
// onFulfilled(value);
// return this;
}
function handle(deferred) {
if (state === 'pending') {
deferreds.push(deferred);
return;
}
var cb = state === 'fulfilled' ? deferred.onFulfilled : deferred.onRejected,
ret;
if (cb === null) {
cb = state === 'fulfilled' ? deferred.resolve : deferred.reject;
cb(value);
return;
}
try {
ret = cb(value);
deferred.resolve(ret);
} catch (e) {
deferred.reject(e);
}
}
function resolve(newValue) {
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
var then = newValue.then;
if (typeof then === 'function') {
then.call(newValue, resolve, reject);
return;
}
}
//通过setTimeout将resolve中执行回调的逻辑放置到JS任务队列末尾
//当fn中为同步操作时强制resolve异步
//即先执行后续的then再调用resolve
value = newValue;
state = 'fulfilled'; //resolve执行时,将状态设置为fulfilled
setTimeout(function () {
deferreds.forEach(function (deferred) {
deferred(value);
})
},0);
}
function reject(newValue) {
state = 'rejected';
value = newValue;
setTimeout(function () {
deferreds.forEach(function (deferred) {
deferred(value);
})
},0);
}
fn(resolve, reject);
}
转载美团点评技术团队关于Promise的一篇文章,将的挺仔细的,值得学习啊。
链接地址: https://tech.meituan.com/techsalon