博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何将现有的回调API转换为Promise?
阅读量:2288 次
发布时间:2019-05-09

本文共 9592 字,大约阅读时间需要 31 分钟。

本文翻译自:

I want to work with promises but I have a callback API in a format like: 我想使用Promise,但是我有一个类似以下格式的回调API:

1. DOM load or other one time event: 1. DOM加载或其他一次事件:

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

2. Plain callback: 2.普通回调:

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

3. Node style callback ("nodeback"): 3.节点样式回调(“ nodeback”):

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

4. A whole library with node style callbacks: 4.带有节点样式回调的整个库:

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

How do I work with the API in promises, how do I "promisify" it? 如何在promise中使用API​​,如何“承诺”它?


#1楼

参考:


#2楼

Promises have state, they start as pending and can settle to: 承诺有状态,它们从待定状态开始,可以解决:

  • fulfilled meaning that the computation completed successfully. 完成意味着计算成功完成。
  • rejected meaning that the computation failed. 拒绝表示计算失败。

Promise returning functions , they should return rejections instead. 承诺返回函数 ,而应该返回拒绝。 Throwing from a promise returning function will force you to use both a } catch {

and a .catch . 从promise返回函数抛出将迫使您同时使用} catch {
.catch
People using promisified APIs do not expect promises to throw. 使用承诺的API的人们不会期望诺言。 If you're not sure how async APIs work in JS - please first. 如果您不确定JS中异步API的工作方式-请首先 。

1. DOM load or other one time event: 1. DOM加载或其他一次事件:

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 ). 因此,创建承诺通常意味着指定何时结算-即何时进入承诺阶段或拒绝阶段以指示数据可用(并且可以通过.then访问)。

With modern promise implementations that support the Promise constructor like native ES6 promises: 使用支持Promise构造函数的现代Promise实现(例如本机ES6 Promise

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

You would then use the resulting promise like so: 然后,您将使用产生的承诺,如下所示:

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

With libraries that support deferred (Let's use $q for this example here, but we'll also use jQuery later): 使用支持延迟的库(让我们在此示例中使用$ q,但稍后我们还将使用jQuery):

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

Or with a jQuery like API, hooking on an event happening once: 或者使用jQuery之类的jQuery,将一次事件挂起:

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

2. Plain callback: 2.普通回调:

These APIs are rather common since well… callbacks are common in JS. 这些API相当常见,因为……在JS中回调很常见。 Let's look at the common case of having onSuccess and onFail : 让我们看一下具有onSuccessonFail的常见情况:

function getUserData(userId, onLoad, onFail) { …

With modern promise implementations that support the Promise constructor like native ES6 promises: 使用支持Promise构造函数的现代Promise实现(例如本机ES6 Promise

function getUserDataAsync(userId) {    return new Promise(function(resolve, reject) {        getUserData(userId, resolve, reject);    });}

With libraries that support deferred (Let's use jQuery for this example here, but we've also used $q above): 使用支持延迟的库(在此示例中,我们使用jQuery,但上面我们也使用$ q):

function getUserDataAsync(userId) {    var d = $.Deferred();    getUserData(userId, function(res){ d.resolve(res); }, function(err){ d.reject(err); });    return d.promise();}

jQuery also offers a $.Deferred(fn) form, which has the advantage of allowing us to write an expression that emulates very closely the new Promise(fn) form, as follows: jQuery还提供了$.Deferred(fn)形式,它的优点是允许我们编写一个非常接近new Promise(fn)形式的表达式,如下所示:

function getUserDataAsync(userId) {    return $.Deferred(function(dfrd) {        getUserData(userId, dfrd.resolve, dfrd.reject);    }).promise();}

Note: Here we exploit the fact that a jQuery deferred's resolve and reject methods are "detachable"; 注意:这里我们利用了一个事实,即jQuery deferred的resolvereject方法是“可分离的”。 ie. 即。 they are bound to the instance of a jQuery.Deferred(). 它们绑定到jQuery.Deferred()的实例 Not all libs offer this feature. 并非所有库都提供此功能。

3. Node style callback ("nodeback"): 3.节点样式回调(“ nodeback”):

Node style callbacks (nodebacks) have a particular format where the callbacks is always the last argument and its first parameter is an error. 节点样式回调(nodebacks)具有特定的格式,其中回调始终是最后一个参数,而其第一个参数是错误。 Let's first promisify one manually: 让我们首先手动分配一个:

getStuff("dataParam", function(err, data) { …

To: 至:

function getStuffAsync(param) {    return new Promise(function(resolve, reject) {        getStuff(param, function(err, data) {            if (err !== null) reject(err);            else resolve(data);        });    });}

With deferreds you can do the following (let's use Q for this example, although Q now supports the new syntax ): 使用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;   }

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. 通常,您不应该过多地手动分配内容,大多数基于Node设计的Promise库以及Node 8+中的本机Promise具有内置的用于使NodeBback富集的方法。 For example 例如

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

4. A whole library with node style callbacks: 4.带有节点样式回调的整个库:

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: 但是,某些promise实现允许您批量执行此操作,例如在Bluebird中,将nodeback API转换为promise API很简单:

Promise.promisifyAll(API);

Or with native promises in Node : 或在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}), {});

Notes: 笔记:

  • Of course, when you are in a .then handler you do not need to promisify things. 当然,当你在一个.then处理你不需要promisify事情。 Returning a promise from a .then handler will resolve or reject with that promise's value. .then处理程序返回一个诺言将解决或拒绝该诺言的值。 Throwing from a .then handler is also good practice and will reject the promise - this is the famous promise throw safety. .then处理程序中抛出也是很好的做法,并且会拒绝诺言-这就是著名的诺言抛出安全性。
  • In an actual onload case, you should use addEventListener rather than onX . 在实际的onload情况下,应该使用addEventListener而不是onX

#3楼

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. 我认为@Benjamin的window.onload建议不会一直有效,因为它无法检测到加载后是否被调用。 I have been bitten by that many times. 我被很多次咬伤了。 Here is a version which should always work: 这是一个应该始终有效的版本:

function promiseDOMready() {    return new Promise(function(resolve) {        if (document.readyState === "complete") return resolve();        document.addEventListener("DOMContentLoaded", resolve);    });}promiseDOMready().then(initOnLoad);

#4楼

The Q library by kriskowal includes callback-to-promise functions. kriskowal的Q库包含应答回调函数。 A method like this: 这样的方法:

obj.prototype.dosomething(params, cb) {  ...blah blah...  cb(error, results);}

can be converted with Q.ninvoke 可以用Q.ninvoke转换

Q.ninvoke(obj,"dosomething",params).then(function(results) {});

#5楼

You can use JavaScript native promises with Node JS. 您可以将JavaScript本机Promise与Node JS一起使用。

My Cloud 9 code link: 我的Cloud 9代码链接: :

/*** Created by dixit-lab on 20/6/16.*/var express = require('express');var request = require('request');   //Simplified HTTP request client.var app = express();function promisify(url) {    return new Promise(function (resolve, reject) {        request.get(url, function (error, response, body) {            if (!error && response.statusCode == 200) {                resolve(body);            }            else {                reject(error);            }        })    });}//get all the albums of a user who have posted post 100app.get('/listAlbums', function (req, res) {    //get the post with post id 100    promisify('http://jsonplaceholder.typicode.com/posts/100').then(function (result) {        var obj = JSON.parse(result);        return promisify('http://jsonplaceholder.typicode.com/users/' + obj.userId + '/albums')    })    .catch(function (e) {        console.log(e);    })    .then(function (result) {        res.end(result);    })})var server = app.listen(8081, function () {    var host = server.address().address    var port = server.address().port    console.log("Example app listening at http://%s:%s", host, port)})//run webservice on browser : http://localhost:8081/listAlbums

#6楼

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. 当您有一些需要回调的函数并且希望它们返回一个Promise时,您可以使用此函数进行转换。

function callbackToPromise(func){    return function(){        // change this to use what ever promise lib you are using        // In this case i'm using angular $q that I exposed on a util module        var defered = util.$q.defer();        var cb = (val) => {            defered.resolve(val);        }        var args = Array.prototype.slice.call(arguments);        args.push(cb);            func.apply(this, args);        return defered.promise;    }}

转载地址:http://jjcnb.baihongyu.com/

你可能感兴趣的文章
IOS 获取网络状态
查看>>
IOS NSDate
查看>>
iOS蓝牙开发:蓝牙连接和数据读写
查看>>
IOS 收集的一些好的文章
查看>>
IOS crash处理
查看>>
解释型语言与编译型语言的区别
查看>>
iOS 生成静态库和动态库
查看>>
Java 观察者模式
查看>>
object-c 和 java 可以通用的DES散列加密
查看>>
IOS MVVM 设计模式
查看>>
Android 中常用的轮子
查看>>
Android Adb 使用大全
查看>>
Android 给textView和editText 添加方框
查看>>
Android 实现歌词滚动
查看>>
Android 多线程
查看>>
Android Service服务(一)
查看>>
Android Service服务(二)
查看>>
愿你历尽千帆,归来仍少年
查看>>
java实现生产者消费者问题
查看>>
Android 数据存储三种方式
查看>>