'catch': function (onRejection) {
return this.then(null, onRejection);
}
};
Promise.resolve(value)
新建promise
调用ResolvePromise(promise, value)(未列出,会判断一些情况然后调用FulfillPromise)
返回promise
Promise.resolve = function (arg) {
var child = new Promise(noop);
resolve(child, arg);
return child;
};
Promise.reject(value)
新建promise
调用RejectPromise(promise, value)
返回promise
Promise.reject = function (reason) {
var child = new Promise(noop);
reject(child, reason);
return child;
};
Promise.all(iterator)
到这里我们已经能够实现基本的promise了,Promise.all和Promise.race就不继续描述了,有兴趣的可以继续去读规范,这里上图来说明我对这两个函数的理解:
promise.all理解
调用promise.all会新建一个对象来存储所有promise的处理状态,保存执行的结果,当remain为0时,就可以resolve 新建的promise,这样就可以继续往后执行了。
Promise.all = function (promises) {
var child = new Promise(noop);
var record = {
remain: promises.length,
values: []
};
promises.forEach(function (promise, i) {
if (promise._state === PENDING) {
subscribe(promise, undefined, onFulfilled(i), onRejected);
} else if (promise._state === REJECTED) {
reject(child, promise._result);
return false;
} else {
--record.remain;
record.values[i] = promise._result;
if (record.remain == 0) {
resolve(child, values);
}
}
});
return child;
function onFulfilled(i) {
return function (val) {
--record.remain;
record.values[i] = val;
if (record.remian === 0) {
resolve(child, record.values);
}
}
}
function onRejected(reason) {
reject(child, reason);
}
};
Promise.race(iterator)
promise.race与promise.all类似,不过只要有一个promise完成了,我们就可以resolve新建的promise了。
Promise.race = function (promises) {
var child = new Promise(noop);
promises.forEach(function (promise, i) {
if (promise._state === PENDING) {
subscribe(promise, undefined, onFulfilled, onRejected);
} else if (promise._state === REJECTED) {
reject(child, promise._result);
return false;
} else {
resolve(child, promise._result);
return false;
}
});
return child;
function onFulfilled(val) {
resolve(child, val);
}
function onRejected(reason) {
reject(child, reason);
}
};
这就是promise的基本内容了,完整代码请戳这里。
其他问题
promises 穿透
如果传入then里面的参数不是函数,实际不会被忽略的,这就是promise穿透的原因,所以永远往then里面传递函数。答案可以从then方法里面调用的一个关键函数invokeCallback中找到答案:
function invokeCallback(settled, promise, callback, detail) {
var hasCallback = (typeof callback === 'function'),
value, error, succeeded, failed;
if (hasCallback) {
try {
value = callback(detail);
} catch (e) {
value = {
error: e
};
}
if (value && !!value.error) {
failed = true;
error = value.error;
value = null;
} else {
succeeded = true;
}