如何将现有的回调API转换为承诺?
我想处理承诺,但我的回调API的格式:
### 1。 DOM负载或其他一次事件:
window.onload; // set to callback
...
window.onload = function() {
};
### 2。普通回调:
function request(onChangeHandler) {
...
}
request(function() {
// change happened
...
});
### 3。节点样式回调(“ nodeback”):
function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})
### 4。一个带有节点样式回调的整个库:
API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});
我如何在承诺中与API一起工作,如何“诺言”?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(24)
承诺有状态,他们开始待定,可以安定下来:
承诺返回函数 永远不要扔 ,他们应该返回拒绝。从承诺返回功能中投掷将迫使您同时使用
} catch {
和 a.catch
。使用Promissied API的人不会期望承诺会抛弃。如果您不确定ASYNC API在JS中的工作原理 - 请请参阅此答案首先。1。DOM加载或其他一次事件:
因此,创建承诺通常意味着指定何时定居 - 这意味着当它们移至满足或拒绝的阶段以指示数据可用(可以使用
>。 /代码>)。
借助支持
Promise
构造函数的现代承诺实现,例如本机ES6承诺:然后,您将使用由此产生的承诺这样的承诺:
使用支持延迟的库(让我们在此处使用$ Q稍后再使用jQuery):
或使用诸如API之类的jQuery,在发生的事件中挂钩:
2。纯回调:
这些API相当普遍,因为好吧……回调在JS中很常见。让我们看一下具有
OnSuccess
和onfail
的常见情况:具有支持
Promise> Promise> Promise
构造函数的现代承诺实现,例如本机ES6 Promises:带有图书馆 :支持延期(让我们在此处使用jQuery进行此示例,但是我们还使用了上面的$ q):
jQuery还提供
$。$。递延(FN)
表单,它具有允许我们写作的优势一种表达式,非常紧密地模拟新的Promise(FN)
表格,如下:注意:在这里我们利用了一个事实,即jQuery deferred的
resolve
and code> andrecood> recood 方法是“可拆卸”; IE。它们被绑定到jQuery.deferred()的实例。并非所有的Libs都提供此功能。
3.节点样式回调(“ NodeBack”):
节点样式回调(NodeBacks)具有特定格式,其中回调始终是最后一个参数,其第一个参数是错误。首先,让我们手动宣传一个:
to:
使用延期,您可以执行以下操作(尽管Q现在支持新的语法您应该更喜欢):
通常,您不应手动地承诺事物过多,大多数承诺库的库都考虑到节点,而Node 8+中的本机承诺具有构架方法,可以促进Nodebacks。例如
4。一个带有节点样式回调的整个库:
这里没有黄金规则,您可以一个人诺言。但是,某些承诺实现使您可以批量执行此操作,例如在蓝鸟中,将节点背API转换为Promise API很简单,就像:
或 native promises in node >:
注意:
中。然后,当您不需要承诺事物时。从
中返回承诺。然后,
处理程序将通过该诺言的价值解决或拒绝。从中投掷。然后,
处理程序也是一个很好的做法,并且会拒绝承诺 - 这是著名的承诺安全。onload
情况下,您应该使用addeventListener
而不是onx
。Promises have state, they start as pending and can settle to:
Promise returning functions should never throw, they should return rejections instead. Throwing from a promise returning function will force you to use both a
} catch {
and a.catch
. People using promisified APIs do not expect promises to throw. If you're not sure how async APIs work in JS - please see this answer first.1. DOM load or other one time event:
So, creating promises generally means specifying when they settle - that means when they move to the fulfilled or rejected phase to indicate the data is available (and can be accessed with
.then
).With modern promise implementations that support the
Promise
constructor like native ES6 promises:You would then use the resulting promise like so:
With libraries that support deferred (Let's use $q for this example here, but we'll also use jQuery later):
Or with a jQuery like API, hooking on an event happening once:
2. Plain callback:
These APIs are rather common since well… callbacks are common in JS. Let's look at the common case of having
onSuccess
andonFail
:With modern promise implementations that support the
Promise
constructor like native ES6 promises:With libraries that support deferred (Let's use jQuery for this example here, but we've also used $q above):
jQuery also offers a
$.Deferred(fn)
form, which has the advantage of allowing us to write an expression that emulates very closely thenew Promise(fn)
form, as follows:Note: Here we exploit the fact that a jQuery deferred's
resolve
andreject
methods are "detachable"; ie. they are bound to the instance of a jQuery.Deferred(). Not all libs offer this feature.3. Node style callback ("nodeback"):
Node style callbacks (nodebacks) have a particular format where the callbacks is always the last argument and its first parameter is an error. Let's first promisify one manually:
To:
With deferreds you can do the following (let's use Q for this example, although Q now supports the new syntax which you should prefer):
In general, you should not promisify things manually too much, most promise libraries that were designed with Node in mind as well as native promises in Node 8+ have a built in method for promisifying nodebacks. For example
4. A whole library with node style callbacks:
There is no golden rule here, you promisify them one by one. However, some promise implementations allow you to do this in bulk, for example in Bluebird, converting a nodeback API to a promise API is as simple as:
Or with native promises in Node:
Notes:
.then
handler you do not need to promisify things. Returning a promise from a.then
handler will resolve or reject with that promise's value. Throwing from a.then
handler is also good practice and will reject the promise - this is the famous promise throw safety.onload
case, you should useaddEventListener
rather thanonX
.今天,我可以在
node.js
中使用Promise
作为普通的JavaScript方法。Promise
的一个简单而基本的示例(使用 方式):plin javaScript ASYNC API代码:
async api代码:
Promise
javascript //exploringjs.com/es6/ch_promises.html“ rel =“ noreferrer”>这个美丽的来源)也可以一起使用
Promise
可以一起使用async \ async \等待
在es7
中,使程序流等待fullfiled
结果如下:使用
。
Promise
也可以在基于node.js的任何平台上使用,例如react-native-native
。奖金:混合方法
(假定回调方法具有两个参数作为错误和结果)
上述方法可以响应旧的时尚回调和承诺用法的结果。
希望这会有所帮助。
Today, I can use
Promise
inNode.js
as a plain Javascript method.A simple and basic example to
Promise
(with KISS way):Plain Javascript Async API code:
Promise
Javascript Async API code:(I recommend visiting this beautiful source)
Also
Promise
can be used with togetherasync\await
inES7
to make the program flow wait for afullfiled
result like the following:Another usage with the same code by using
.then()
methodPromise
can also be used on any platform that is based on Node.js likereact-native
.Bonus: An hybrid method
(The callback method is assumed to have two parameters as error and result)
The above method can respond result for old fashion callback and Promise usages.
Hope this helps.
在将函数转换为Node.js
转换后
Incase之前,您需要处理多个请求
Before converting a function as promise In Node.JS
After Converting It
Incase you need to handle multiple request
node.js 8.0.0包括新的 /a> API允许标准Node.js回调样式API包裹在返回承诺的函数中。
util.promisify()
的示例使用如下所示。请参阅改进的承诺支持
Node.js 8.0.0 includes a new
util.promisify()
API that allows standard Node.js callback style APIs to be wrapped in a function that returns a Promise. An example use ofutil.promisify()
is shown below.See Improved support for Promises
我认为@benjamin的建议 @benjamin不会一直工作,因为它无法检测到加载后是否调用它。我被这么多次咬了。这是一个应该始终工作的版本:
I don't think the
window.onload
suggestion by @Benjamin will work all the time, as it doesn't detect whether it is called after the load. I have been bitten by that many times. Here is a version which should always work:我通常使用的简单通用功能。
如何使用
prosisify
接受带回调的函数:您可能不是在寻找此答案,但这将有助于了解可用utils的内部工作
A simple generic function I normally use.
How to use it
promisify
accepts a function with a callback:You are probably not looking for this answer, but this will help understand the inner workings of the available utils
在node.js 8.0.0的发行候选中,有一个新的实用程序,
util.promisify
(我已经写了 util.promisify ),它封装了授权任何功能的能力。它与其他答案中建议的方法没有太大不同,但具有成为核心方法的优势,而不是需要其他依赖性。
然后,您是
ReadFile
方法,该方法返回本机Promise
。In release candidate for Node.js 8.0.0, there's a new utility,
util.promisify
(I've written about util.promisify), that encapsulates the capacity of promisifying whatever function.It is not much different from the approaches suggested in the other answers, but has the advantage of being a core method, and not requiring additional dependencies.
Then you've a
readFile
method that returns a nativePromise
.您可以使用节点JS使用JavaScript本机承诺。
我的云9代码链接: https:///////ide.c9.io/adx2803/native - 启示性节点
You can use JavaScript native promises with Node JS.
My Cloud 9 code link: https://ide.c9.io/adx2803/native-promises-in-node
借助普通的旧香草JavaScript,这是一个解决API回调的解决方案。
With plain old vanilla javaScript, here's a solution to promisify an api callback.
Kriskowal的Q库包括回调对启示功能。
这样的方法:
可以用q.ninvoke转换
The Q library by kriskowal includes callback-to-promise functions.
A method like this:
can be converted with Q.ninvoke
当您有几个功能可以进行回调时,您希望他们返回诺言,您可以使用此功能进行转换。
When you have a few functions that take a callback and you want them to return a promise instead you can use this function to do the conversion.
在Node v7.6+下,已内置的诺言和异步:
如何使用:
Under node v7.6+ which has built in promises and async:
How to use:
在node.js 8中,您可以使用此NPM模块 对象方法 使用此npm模块:
https://www.npmjs.com/package/doasync
它使用 util.promisify 和 proxies 不变。 回忆也可以使用弱图的使用来完成。以下是一些示例:
带有对象:
带有函数:
您甚至可以使用本机
呼叫
和应用
来绑定某些上下文:In Node.js 8 you can promisify object methods on the fly using this npm module:
https://www.npmjs.com/package/doasync
It uses util.promisify and Proxies so that your objects stay unchanged. Memoization is also done with the use of WeakMaps). Here are some examples:
With objects:
With functions:
You can even use native
call
andapply
to bind some context:您可以在ES6中使用本地Promise 来处理Settimeout:
在此典范中,承诺没有理由失败,因此
recond> recond> recond()
从未被调用。You can use native Promise in ES6, for exemple dealing with setTimeout:
In this exemple, the Promise has no reason to fail, so
reject()
is never called.ES6-启示录
将基于回调的功能转换为基于承诺的功能。参考: https://www.npmjs.com/package/package/es6-promisify
es6-promisify
converts callback-based functions to Promise-based functions.Ref: https://www.npmjs.com/package/es6-promisify
您可以做这样的事情
,然后使用它
You can do something like this
Then use it
回调样式函数始终像这样(Node.js中的几乎所有函数都是此样式):
此样式具有相同的功能:
回调函数通过最后一个参数传递。
回调函数始终接受错误对象作为第一个参数。
因此,您可以编写一个函数,以转换这样的函数:
对于更简洁的示例,示例使用了ramda.js。 Ramda.js是功能编程的绝佳库。在上面的代码中,我们使用的是应用(例如javascript
function.prototype.apply
)和附加(例如javascriptfunction.prototype.prototype.push.push
)。因此,我们现在可以将回调样式函数转换为Prome Style函数:
topromise 和 checkerr 函数是 berserk 库,这是 ramda.js 的功能编程库叉(由我创建)。
希望这个答案对您有用。
The callback style function always like this(almost all function in node.js is this style):
This style has same feature:
the callback function is passed by last argument.
the callback function always accept the error object as it's first argument.
So, you could write a function for convert a function with this style like this:
For more concise, above example used ramda.js. Ramda.js is a excellent library for functional programming. In above code, we used it's apply(like javascript
function.prototype.apply
) and append(like javascriptfunction.prototype.push
).So, we could convert the a callback style function to promise style function now:
toPromise and checkErr function is own by berserk library, it's a functional programming library fork by ramda.js(create by me).
Hope this answer is useful for you.
我
回调
函数的委托版本是p
函数:p
函数要求回调签名必须为回调(错误,结果)
。My promisify version of a
callback
function is theP
function:The
P
function requires that the callback signature must becallback(error,result)
.以下是如何将函数(回调API)转换为承诺的实现。
Below is the implementation of how a function (callback API) can be converted to a promise.
承诺始终具有
Resolve
和拒绝
。当您编写异步包装器时,只需调用分辨率,然后就可以了。您可以为几乎任何功能编写包装函数,以便进行回调这样的功能:
您可以进一步将回调的转换功能写入承诺:
当使用较旧的库或SDK时,包装器功能的概念尤其有用。例如,考虑Facebook Graph API的JavaScript SDK,该JavaScript SDK使用类似的回调结构来制作API请求。
在现代应用程序中,使用基于承诺的API要有用得多。
如果您仅使用一次或两次函数,则最好单独诺言:
如果您经常使用该函数,则可以使用相同的包装器概念来编写这样的函数:
尽管有时候有时会很棒,但他们会赢对于这样的特定实例。在这样的时代,请在Github上查找现代包装纸,或这样写自己的包装。
Promises always have a
resolve
and areject
. When you write an async wrapper, just call the resolve and there you go.You can write a wrapper function for pretty much any function taking a callback like so:
You can take this further to write a conversion function of callbacks to promises:
This concept of wrapper functions is especially useful when using older libraries or SDKs. For example, consider the Facebook Graph API's JavaScript SDK, which uses a similar callback structure for making API requests.
In modern applications, it is much more useful to use a promise-based API.
If you use a function only once or twice, it may be better to promisify the response individually:
If you use the function a lot, you can use the same wrapper concept to write a function like so:
Although promisifiers are great sometimes, they won't work for specific instances like this. In times like these, look on Github for a modern wrapper, or write your own like this.
也许已经回答了,但这是我通常这样做的:
或者,您可能会发现
Future
的这种变化是更通用的Perhaps already answered, but this is how I do it typically:
Or you might find this variation of
Future
to be more general purpose坏死有点 noreflow noreferrer
“在此答案结束时查看摘要示例
写入/转换函数,可以称为
cb(错误,结果)
或或new Promise(...)
格式PromisetoCB
转换并导出了先前已编码的现有函数,该功能返回了Promisecbtopromise
转换并导出以前编码的现有函数,该函数以前被编码为最后一个参数(错误,结果,结果,结果) )cb(未定义,路径,stat)
--->resolve([Path,stat])
/cb(undefined,[path,stat])
aspromise
允许您代码一个新功能以返回承诺,但可以将其称为cb(err,结果)
ascallback
允许您编码 进行2个参数,并根据随机数解决/拒绝/错误。ARG2也可用于强迫通过或失败。 (寻找“ -pass”或“ -fail”)。
包装现有函数
promisetocb(函数myfunc(){},newthis);
)或代码新功能(嵌入包装器)。
测试上述功能的SCIPT
Necromancing a little, bit this link may be useful....
TLDR; look at the snippet example at the end of this answer
write/convert functions that can be called expecting
a
cb(error,result)
ornew Promise (...)
formatpromiseToCB
converts and exports an existing function that's been previously coded to return a promisecbToPromise
converts and exports an existing function that's been previously coded to call the last argument with (error,result)cb(undefined,path,stat)
--->resolve([path,stat])
/cb(undefined,[path,stat])
asPromise
lets you code a new function to return a promise, but it can be called either wayasCallback
lets you code a new function to callcb(err,result)
, but it can be invoked either waysample functions
each sample takes 2 arguments, and resolves/rejects/errors based on random number.
arg2 can be also be used to force pass or fail. (looks for "-pass" or "-fail").
wrap existing functions
promiseToCB(function myFunc(){},newThis);
)or code new functions, which embed a wrapper.
test scipt for above functions
由于我们知道预先基于回调的功能的特征,因此
我们可以创建一个转换基于回调功能的函数
归还承诺的等效功能。
回调是函数的最后一个参数
的最后一个参数,如果有错误,它始终将第一个参数传递给回调
错误之后的任何返回值将传递给回调
since we know the characteristics of a callback-based function in advance,
we can create a function that transforms a callback-based function
into an equivalent function returning a Promise.
The callback is the last argument of the function
If there is an error, it always the first argument passed to the callback
Any return value is passed after the error to the callback
大约迟到了5年,但是我想在这里发布我的Promesify版本,该版本从回调API中获取功能,并将其变成承诺,
请在此处查看此非常简单的版本:
It is like 5 years late, but I wanted to post here my promesify version which takes functions from callbacks API and turns them into promises
Take a look to this very simple version here:
https://gist.github.com/jdtorregrosas/aeee96dd07558a5d18db1ff02f31e21a