在2017年,Promises内置在Javascript中,并由ES2015规范添加(polyfill可用于IE8-IE11等过时的环境)。他们使用的语法使用传递给
Promise构造函数(
Promiseexecutor)的回调,该回调函数接收用于解析/拒绝promise的函数作为参数。
首先,由于
async现在在Javascript中具有含义(即使在某些情况下只是一个关键字),我将使用它
later作为函数的名称以避免混淆。基本延迟
使用本机的Promise(或忠实的polyfill)看起来像这样:
function later(delay) { return new Promise(function(resolve) { setTimeout(resolve, delay); });}
需要注意的是,它假定的一个版本,
setTimeout这是符合该定义的浏览器,其中
setTimeout不传递任何参数的回调,除非你给他们的时间间隔后(这可能不是在非浏览器环境中真实的,并没有曾经是在Firefox上为true,但现在是;在Chrome上甚至在IE8上都为true)。具有价值的基本延迟
如果您希望函数有选择地传递分辨率值,请在任何模糊的现代浏览器上允许您
setTimeout在延迟后提供额外的参数,然后在调用时将其传递给回调,您可以执行此 *** 作(当前Firefox和Chrome;IE11 + ,大概是Edge; 不是 IE8或IE9, 不了解 IE10):
function later(delay, value) { return new Promise(function(resolve) { setTimeout(resolve, delay, value); // Note the order, `delay` before `value` });}
如果您使用的是ES2015 +箭头功能,则可以更加简洁:
function later(delay, value) { return new Promise(resolve => setTimeout(resolve, delay, value));}
甚至
值可取消的延迟const later = (delay, value) => new Promise(resolve => setTimeout(resolve, delay, value));
如果您想取消超时,则不能只从中返回承诺
later,因为不能取消承诺。
但是,我们可以轻松地用
cancel承诺的方法和访问器返回对象,并在取消时拒绝承诺:
const later = (delay, value) => { let timer = 0; let reject = null; const promise = new Promise((resolve, _reject) => { reject = _reject; timer = setTimeout(resolve, delay, value); }); return { get promise() { return promise; }, cancel() { if (timer) { clearTimeout(timer); timer = 0; reject(); reject = null; } } };};
现场示例:
const later = (delay, value) => { let timer = 0; let reject = null; const promise = new Promise((resolve, _reject) => { reject = _reject; timer = setTimeout(resolve, delay, value); }); return { get promise() { return promise; }, cancel() { if (timer) { clearTimeout(timer); timer = 0; reject(); reject = null; } } };};const l1 = later(100, "l1");l1.promise .then(msg => { console.log(msg); }) .catch(() => { console.log("l1 cancelled"); });const l2 = later(200, "l2");l2.promise .then(msg => { console.log(msg); }) .catch(() => { console.log("l2 cancelled"); });setTimeout(() => { l2.cancel();}, 150);
2014年的原始答案
通常,您将拥有一个Promise库(一个是您自己编写的,或者是其中几个库中的一个)。该库通常会有一个您可以创建并稍后“解析”的对象,而该对象将有一个您可以从中获得的“承诺”。
然后
later往往看起来像这样:
function later() { var p = new PromiseThingy(); setTimeout(function() { p.resolve(); }, 2000); return p.promise(); // Note we're not returning `p` directly}
在对问题的评论中,我问:
您是否正在尝试创建自己的Promise库?
你说
我不是,但我现在想这就是我想要了解的内容。那图书馆怎么做
<!DOCTYPE html><html><head><meta charset=utf-8 /><title>Very basic promises</title></head><body> <script> (function() { // ==== Very basic promise implementation, not remotely Promises-A compliant, just a very basic example var PromiseThingy = (function() { // Internal - trigger a callback function triggerCallback(callback, promise) { try { callback(promise.resolvedValue); } catch (e) { } } // The internal promise constructor, we don't share this function Promise() { this.callbacks = []; } // Register a 'then' callback Promise.prototype.then = function(callback) { var thispromise = this; if (!this.resolved) { // Not resolved yet, remember the callback this.callbacks.push(callback); } else { // Resolved; trigger callback right away, but always async setTimeout(function() { triggerCallback(callback, thispromise); }, 0); } return this; }; // Our public constructor for PromiseThingys function PromiseThingy() { this.p = new Promise(); } // Resolve our underlying promise PromiseThingy.prototype.resolve = function(value) { var n; if (!this.p.resolved) { this.p.resolved = true; this.p.resolvedValue = value; for (n = 0; n < this.p.callbacks.length; ++n) { triggerCallback(this.p.callbacks[n], this.p); } } }; // Get our underlying promise PromiseThingy.prototype.promise = function() { return this.p; }; // Export public return PromiseThingy; })(); // ==== Using it function later() { var p = new PromiseThingy(); setTimeout(function() { p.resolve(); }, 2000); return p.promise(); // Note we're not returning `p` directly } display("Start " + Date.now()); later().then(function() { display("Done1 " + Date.now()); }).then(function() { display("Done2 " + Date.now()); }); function display(msg) { var p = document.createElement('p'); p.innerHTML = String(msg); document.body.appendChild(p); } })(); </script></body></html>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)