admin管理员组文章数量:1336734
After watching fun fun function, I decided not to use the new
keyword.
But here is a foundational example of how to use promises:
var promise = new Promise(function(resolve, reject) {
// do a thing, possibly async, then…
if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
Q: How do I create a promise without the use of the new
keyword?
After watching fun fun function, I decided not to use the new
keyword.
But here is a foundational example of how to use promises:
var promise = new Promise(function(resolve, reject) {
// do a thing, possibly async, then…
if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
Q: How do I create a promise without the use of the new
keyword?
-
1
Why have you decided not to use the
new
keyword? Did you watch and understand the video? You can follow the example in the video exactly... not sure what you are trying to acplish. – skyline3000 Commented Sep 19, 2017 at 19:44 -
2
Promise is an object. If it so, it should be used with
new
for creation new examples of this object... – Sergey Commented Sep 19, 2017 at 19:55 - 5 Don't trust every video you watch on YouTube. – robertklep Commented Sep 19, 2017 at 20:01
-
@Sergey,
new
does not create new examples of thePromise
object.Promise
is a constructor (a function). You create examples ofPromise.prototype
, notPromise
. – trincot Commented Sep 20, 2017 at 7:57 - 1 Seems like a pretty pointless objective to avoid the supported and well understood and simple way of creating a promise. – jfriend00 Commented Sep 20, 2017 at 22:08
4 Answers
Reset to default 4As a pure academic question, you could work around new
by creating a thenable (for which you don't need new
), and then you can convert that thenable to a full-blown promise with Promise.resolve
:
function createPromise(executor) {
let callback;
function resolve(resolution, arg) {
Promise.resolve().then(function () {
callback[resolution](arg);
});
}
try {
executor(resolve.bind(null, "fulfill"), resolve.bind(null, "reject"));
} catch(e) {
resolve("reject", e);
}
return Promise.resolve({
then: function (fulfill, reject) {
callback = { fulfill, reject };
}
});
}
// Demo
var prom1 = createPromise(function (resolve, reject) {
setTimeout(function () { resolve("Stuff worked!") }, 1000);
});
var prom2 = createPromise(function (resolve, reject) {
setTimeout(function () { reject("It broke") }, 1000);
});
prom1.then(function (v) { console.log(v); });
prom2.catch(function (err) { console.log(err) });
console.log('waiting for promises to resolve');
Some have reasons to avoid the use of new
, but if that has to lead to the above code, then clearly some exceptions should be allowed. Unless someone has a better idea to create promises without the use of new
, one has to implement some Promise characteristics again (such as the try ... catch
and the asynchronous call of the then
callback) only to work around new
. This seems a bad idea.
Conclusion: just use new
for creating new promises.
Use async/await
const getPromise = async () => {
// do a thing, possibly async, then…
if (/* everything turned out fine */) {
return 'Stuff worked!'
} else {
throw 'It broke'
}
});
const promise = getPromise()
But please realize that you can't just call Error
, calling constructor without new
keyword throws garbage to global
object in NodeJS (or to window
object in browser JS). You have to use new Error
. I hope I didn't create a whole new problem for you.
Also, note that async/await
is just a syntactic sugar, the code will run with new
anyway. Also, I suggest not to take advice literally. Granted, new
is evil, but sometimes necessary in order not to over-plicate things.
MDN's Promise.resolve() and Promise.reject()
man pages show how those functions return then
ables.
The following code snippet goes a step further to show how they can be used to make myFunc
wrap _myFunc
to return a then
able.
'strict';
function _myFunc(tf){
if (tf)
return;
throw new Error('flubbed it');
}
function myFunc(tf){
try { return Promise.resolve(_myFunc(tf));}
catch(e) { return Promise.reject(e);}
}
function main() {
try {
_myFunc(false);
console.log('SUCCESS');
} catch (e) {
console.log(`FAILED: ${e.message}`);
}
try {
_myFunc(true);
console.log('SUCCESS');
} catch (e) {
console.log(`FAILED: ${e.message}`);
}
myFunc(false)
.then(()=>{ console.log('success'); })
.catch((e)=>{ console.log(`failed: ${e.message}`); });
myFunc(true)
.then(()=>{ console.log('success'); })
.catch((e)=>{ console.log(`failed: ${e.message}`); });
}
main();
However, because there are no promises, there is no await
either, and we are back to the pyramid of doom when it es to synchronizing.
As you can see in the output
FAILED: flubbed it
SUCCESS
success
failed: flubbed it
the order of last two results are out of order. That is because the JS interpreter sees the use of a then
able as an instruction to run the mand asynchronously.
In conclusion, the great thing about Promise
s is the ability to await
and use Promise.all
or Promise.race
etc, which require Promise
s with state, for which new Promise(...)
is obviously required.
You can use a wrapper function:
const Guarantee = function () {
var _resolve = null
var _reject = null
var promise = new Promise(function (resolve, reject) {
_resolve = resolve
_reject = reject
})
promise.resolve = function () {
_resolve.apply(promise, arguments)
}
promise.reject = function () {
_resolve.apply(promise, arguments)
}
return promise
}
function doSomething () {
const promise = Guarantee()
setTimeout(function () {
promise.resolve('123')
}, 1000)
return promise
}
doSomething()
.then(function (data) {
console.log(data)
})
- https://github./webarthur/node-guarantee
- https://www.npmjs./package/node-guarantee
Enjoy!
本文标签: javascriptCreating a promise without the new keywordStack Overflow
版权声明:本文标题:javascript - Creating a promise without the new keyword - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742335504a2455542.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论