我想使用Promise,但是我有一个类似以下格式的回调API:
window.onload; // set to callback
...
window.onload = function() {
};
function request(onChangeHandler) {
...
}
request(function() {
// change happened
...
});
function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})
API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});
承诺有状态,它们从待定状态开始,可以解决:
承诺返回函数 绝不应该抛出,而应该返回拒绝。从promise返回函数抛出将迫使您同时使用a } catch {
和 a.catch
。使用承诺的API的人们不会期望诺言。
因此,创建承诺通常意味着指定它们的结算时间-这意味着它们何时进入完成或拒绝阶段以指示数据可用(并且可以通过访问.then
)。
通过支持Promise
本地构造函数的现代Promise实现(例如本机ES6 Promise):
function load() {
return new Promise(function(resolve, reject) {
window.onload = resolve;
});
}
然后,您将使用产生的承诺,如下所示:
load().then(function() {
// Do things after onload
});
使用支持延迟的库(让我们在此示例中使用$ q,但稍后我们还将使用jQuery):
function load() {
var d = $q.defer();
window.onload = function() { d.resolve(); };
return d.promise;
}
或使用API之类的jQuery,将一次发生的事件挂钩:
function done() {
var d = $.Deferred();
$("#myObject").once("click",function() {
d.resolve();
});
return d.promise();
}
这些API相当常见,因为……在JS中回调很常见。让我们看看具有onSuccess
and 的常见情况onFail
:
function getUserData(userId, onLoad, onFail) { …
通过支持Promise
本地构造函数的现代Promise实现(例如本机ES6 Promise):
function getUserDataAsync(userId) {
return new Promise(function(resolve, reject) {
getUserData(userId, resolve, reject);
});
}
使用支持延迟的库(在此示例中,我们使用jQuery,但上面我们也使用了$ q):
function getUserDataAsync(userId) {
var d = $.Deferred();
getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); });
return d.promise();
}
jQuery还提供了一种$.Deferred(fn)
表单,其优点是允许我们编写一个非常new Promise(fn)
类似于该表单的表达式,如下所示:
function getUserDataAsync(userId) {
return $.Deferred(function(dfrd) {
getUserData(userId, dfrd.resolve, dfrd.reject);
}).promise();
}
注意:这里我们利用了jQuery的deferred resolve
和reject
方法是“可分离的”
这一事实。即。它们绑定到jQuery.Deferred()的 实例 。并非所有库都提供此功能。
节点样式回调(nodebacks)具有特定的格式,其中回调始终是最后一个参数,而其第一个参数是错误。首先让我们手动分配一个:
getStuff("dataParam", function(err, data) { …
至:
function getStuffAsync(param) {
return new Promise(function(resolve, reject) {
getStuff(param, function(err, data) {
if (err !== null) reject(err);
else resolve(data);
});
});
}
使用deferred,您可以执行以下操作(在本示例中,请使用Q,尽管Q现在支持您应该使用的新语法):
function getStuffAsync(param) {
var d = Q.defer();
getStuff(param, function(err, data) {
if (err !== null) d.reject(err);
else d.resolve(data);
});
return d.promise;
}
通常,您不应该过多地手动分配内容,大多数基于Node设计的Promise库以及Node
8+中的本机Promise具有内置的用于使NodeBbacks富集的方法。例如
var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q
var getStuffAsync = util.promisify(getStuff); // Native promises, node only
这里没有黄金法则,您一一承诺。但是,某些promise实现允许您批量执行此操作,例如在Bluebird中,将nodeback API转换为promiseAPI很简单:
Promise.promisifyAll(API);
或在 Node中* 具有 本机承诺 : *
const { promisify } = require('util');
const promiseAPI = Object.entries(API).map(([key, v]) => ({key, fn: promisify(v)}))
.reduce((o, p) => Object.assign(o, {[p.key]: p.fn}), {});
笔记:
.then
处理程序中时,您不需要散布事物。从.then
处理程序返回一个承诺将解决或拒绝该承诺的值。从.then
处理程序中扔出也是一种好习惯,并且会拒绝诺言-这就是著名的诺言抛出安全性。onload
情况下,您应该使用addEventListener
而不是onX
。问题内容: 我想使用Promise,但是我有一个类似以下格式的回调API: 1. DOM加载或其他一次事件: 2.普通回调: 3.节点样式回调(“ nodeback”): 4.带有节点样式回调的整个库: 如何在Promise中使用API,如何“承诺”呢? 问题答案: 承诺具有状态,它们从待定状态开始,可以解决: fulfilled成 意味着计算成功完成。 fulfilled 表示计算失败。 承
问题内容: 我正在使用播放框架和Apache Kafka。 我有一个POST方法,它将消息发送到Kafka。Kafka有一个API方法 public java.util.concurrent.Future send(ProducerRecord记录,回调回调) 其中Javadoc说 异步将记录发送到主题,并在确认发送后调用提供的回调。 我正在使用play框架公开此功能。我想从Controller方
我正在使用play框架和Apache Kafka。 我有一个POST方法,它向Kafka发送消息。Kafka有一个API方法 公共java.util.concurrent。未来发送(生产记录记录、回调) 其中Javadoc说 异步发送记录到主题,并在发送被确认时调用提供的回调。 我将使用play框架公开此功能。我想返回一个<代码>promise
问题内容: 我正在使用的库使用回调对象发出一系列对象。 使用某些调用添加回调,并使用非阻塞方法调用启动该过程。 创建将发射这些对象的的最佳方法是什么? 如果阻止了该怎么办? 问题答案: 我认为您需要这样的东西(scala中给出的示例) 至于阻塞/非阻塞:通常,基于回调的体系结构将回调订阅与进程启动分开。在这种情况下,您可以完全独立于进程的时间创建任意数量的。另外,是否分叉的决定完全取决于您。您的体
问题内容: 以下函数从url获取图像并进行加载,然后返回其宽度和高度: 问题是,如果我做这样的事情: 我得到,因为该函数运行但图像尚未加载。 仅当照片已加载且宽度和高度已可用时,如何使用等待/异步返回值? 问题答案: 如何使用/ 将此回调函数转换为Promise? 你不知道与往常一样,您可以使用构造函数。没有语法糖。 仅当照片已加载且宽度和高度已经可用时,如何使用/ 记录值? 你可以做
问题内容: 我使用以下代码将密钥转换为字节 现在如何从中获取密钥?我试过了: 我收到以下错误: 问题答案: 这应该工作