我正在深入研究ES6原生Promise。在此过程中,我发现了一些引用Douglas Crockford design choices关于使用new
,Object.create
,this
等内容的 not 的文章。有些人是主张使用Factory Functions而不是构造函数。我还了解到有很多关于这些选择的heated debate。因此,为了避免将此问题列为而非建设性,我想问一下这个具体问题。
如何在不使用 new 的情况下为Promise创建工厂函数?
// from [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
console.log(promise1);
// expected output: [object Promise]
对于使用为Headers()
构建新 fetch
之类的内容也是如此。
在工厂功能的某个时刻,我将不得不写:
new Promise();
DC和其他作者是否只引用自定义对象,而不是内置对象?那些需要使用 new 的所有其他API's呢?
答案 0 :(得分:0)
无论如何,您需要在某个地方拨打new
关键字。你已经完成了99%。
function promiseFactory(bodyFunc) {
return new Promise(bodyFunc);
}
并使用
const promise = promiseFactory((resolve, reject) => setTimeout(resolve, 100, 'foo'));
实施例
function promiseFactory(bodyFunc) {
return new Promise(bodyFunc);
}
const promise1 = promiseFactory((resolve, reject) => setTimeout(resolve, 100, 'foo'));
const promise2 = promiseFactory((resolve, reject) => setTimeout(resolve, 500, 'boo'));
promise1.then(r => console.log(r));
promise2.then(r => console.log(r));
如果您想使用已经解决或拒绝的Promise,则可以分别使用Promise.resolve和Promise.reject。
答案 1 :(得分:0)
如果你有一个“类似”的功能需要你用new
关键字来调用它,你可以使用Object.create
函数将它转换为工厂函数。喜欢这个
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
console.log(this.name);
}
const makePerson = (name) => {
const person = Object.create(Person.prototype);
Person.call(person, name);
return person;
}
makePerson('Joe').sayHi()
但这不适用于Promise,因为(来自规范)
Promise并不打算作为一个函数调用,而是抛出一个函数 以这种方式调用时的异常。
const makePromise = (executor) => {
const promise = Object.create(Promise.prototype);
Promise.call(promise, executor); //this line throws
return promise;
}
try {
makePromise(resolve => setTimeout(resolve, 1000, 'Hi!')).then(console.log)
} catch(e) {
console.error('Crashed due to ', e.message)
}
再次但有一个终极工厂,它附带Reflect API Reflect.construct
。因此,如果您想不惜一切代价避免使用new
,可以像这样做
const makePromise = (executor) => {
return Reflect.construct(Promise, [executor], Promise)
}
makePromise(resolve => setTimeout(resolve, 1000, 'Hi!'))
.then(console.log);