观看fun fun function后,我决定不使用new
关键字。
但这是如何使用承诺的基本示例:
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"));
}
});
问:如何在不使用new
关键字的情况下创建承诺?
答案 0 :(得分:2)
使用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()
但请注意,您不能只调用Error
,调用没有new
关键字的构造函数会将NodeJS(或global
}对象中的window
对象抛出在浏览器JS)。您必须使用new Error
。我希望我没有为你创造一个全新的问题。
另外,请注意async/await
只是一个语法糖,无论如何代码都会以new
运行。另外,我建议不要从字面上理解。当然,new
是邪恶的,但有时是必要的,以免过度复杂化。
答案 1 :(得分:2)
作为一个纯粹的学术问题,你可以通过创建一个(不需要new
)来设置new
,然后你可以转换它可以通过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');
有些人有理由避免使用new
,但如果必须导致上述代码,那么显然应该允许一些例外。除非有人在不使用new
的情况下更好地创建promises,否则必须再次实现一些Promise特性 (例如try ... catch
和异步< / em>调用then
回调)只能解决new
。这似乎是一个坏主意。
结论:只需使用new
来创建新的承诺。
答案 2 :(得分:1)
MDN的Promise.resolve()和Promise.reject()
手册页显示了这些函数如何返回then
ables。
以下代码段进一步说明了如何使用它们来myFunc
包装_myFunc
以返回then
可用。
'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();
但是,由于没有承诺,所以也没有await
,并且在进行同步时我们回到pyramid of doom。
如您在输出中所见
FAILED: flubbed it
SUCCESS
success
failed: flubbed it
最后两个结果的顺序不正确。这是因为JS解释器认为可以使用then
作为指令来异步运行命令。
总而言之,Promise
的伟大之处在于能够await
并使用Promise.all
或Promise.race
等,这需要Promise
的状态,显然需要new Promise(...)
。
答案 3 :(得分:0)
您可以使用包装函数:
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)
})
享受!