gpt4 book ai didi

javascript - 如何将现有的回调 API 转换为 promise ?

转载 作者:行者123 更新时间:2023-11-28 09:05:03 25 4
gpt4 key购买 nike

我想使用 promises,但我有一个格式如下的回调 API:

1。 DOM 加载或其他一次性事件:

window.onload; // set to callback
...
window.onload = function() {

};

2。普通回调:

function request(onChangeHandler) {
...
}
request(function() {
// change happened
...
});

3。 Node 样式回调(“nodeback”):

function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})

4。具有 Node 样式回调的整个库:

API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});

如何在 promises 中使用 API,如何“promisify”它?

最佳答案

Promise 有状态,它们开始时处于待处理状态,可以稳定到:

  • fulfilled 表示计算成功完成。
  • rejected 表示计算失败。

promise 返回函数 should never throw ,他们应该返回拒绝。从 promise 返回函数中抛出将迫使您同时使用 } catch { .catch。使用 promisified API 的人不希望 promises 抛出。如果您不确定异步 API 在 JS 中的工作方式 - 请 see this answer首先。

1。 DOM 加载或其他一次性事件:

因此,创建 promise 通常意味着指定它们何时结算 - 这意味着它们何时进入已完成或已拒绝阶段以指示数据可用(并且可以通过 .then 访问)。

使用支持 Promise 构造函数的现代 promise 实现,例如原生 ES6 promises:

function load() {
return new Promise(function(resolve, reject) {
window.onload = resolve;
});
}

然后您将像这样使用结果 promise :

load().then(function() {
// Do things after onload
});

使用支持 deferred 的库(我们在此示例中使用 $q,但稍后我们也会使用 jQuery):

function load() {
var d = $q.defer();
window.onload = function() { d.resolve(); };
return d.promise;
}

或者使用类似 jQuery 的 API, Hook 发生一次的事件:

function done() {
var d = $.Deferred();
$("#myObject").once("click",function() {
d.resolve();
});
return d.promise();
}

2。普通回调:

这些 API 很常见,因为……回调在 JS 中很常见。让我们看一下具有 onSuccessonFail 的常见情况:

function getUserData(userId, onLoad, onFail) { …

使用支持 Promise 构造函数的现代 promise 实现,例如原生 ES6 promises:

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 的 resolvereject 方法是“可分离的”这一事实; IE。它们绑定(bind)到 jQuery.Deferred() 的实例。并非所有库都提供此功能。

3。 Node 样式回调(“nodeback”):

Node 样式回调 (nodebacks) 具有特定格式,其中回调始终是最后一个参数,其第一个参数是错误。让我们首先手动 promise 一个:

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);
});
});
}

使用 deferreds 你可以做以下事情(让我们用 Q 作为这个例子,尽管 Q 现在支持新的语法 which you should prefer ):

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;
}

一般来说,您不应该过多地手动 promise 事情,大多数在设计时考虑到 Node 的 promise 库以及 Node 8+ 中的原生 promise 都有一个内置的 promise Node 返回的方法。例如

var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q
var getStuffAsync = util.promisify(getStuff); // Native promises, node only

4。具有 Node 样式回调的整个库:

这里没有金科 Jade 律,你一一 promise 。但是,一些 promise 实现允许您批量执行此操作,例如在 Bluebird 中,将 nodeback API 转换为 promise API 非常简单:

Promise.promisifyAll(API);

或者在 Node 中使用 native promise:

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 处理程序中时,您不需要 promise 任何事情。从 .then 处理程序返回 promise 将使用该 promise 的值解决或拒绝。从 .then 处理程序中抛出也是一种很好的做法,并且会拒绝 promise ——这就是著名的 promise 抛出安全性。
  • 在实际的onload 情况下,您应该使用addEventListener 而不是onX

关于javascript - 如何将现有的回调 API 转换为 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26749828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com