如何将使用多个回调的JavaScript函数转换为使用承诺?
我正在尝试将使用异步函数的方式从回调转换为承诺 我理解这里显示的这种基本转换,其中回调被转换为如何将使用多个回调的JavaScript函数转换为使用承诺?,javascript,promise,callback,es6-promise,Javascript,Promise,Callback,Es6 Promise,我正在尝试将使用异步函数的方式从回调转换为承诺 我理解这里显示的这种基本转换,其中回调被转换为resolve和reject函数: // CALLBACK const getData = (id, callback) => { setTimeout(() => { if (!id) return callback('ERROR: id is missing') return callback("The data for id "
resolve
和reject
函数:
// CALLBACK
const getData = (id, callback) => {
setTimeout(() => {
if (!id) return callback('ERROR: id is missing')
return callback("The data for id " + id);
}, 1000)
};
getData(111, console.log);
getData(222, console.log);
getData(null, console.log);
// PROMISE
const getData2 = id => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (!id) reject('id is missing');
resolve("The data for id " + id);
}, 1000);
});
};
getData2(333).then(console.log).catch((message) => console.log("ERROR: " + message));
getData2(444).then(console.log).catch((message) => console.log("ERROR: " + message));
getData2(null).then(console.log).catch((message) => console.log("ERROR: " + message));
但是我经常在下面的场景中使用回调,在这个场景中,您可以有一个需要很长时间的进程,并在调用代码处理信息时,通过多次回调向调用代码发送数据位:
sleep = function (ms) {
var start = new Date().getTime();
let now = 0;
let difference = 0;
for (var i = 0; i < 1e17; i++) {
now = new Date().getTime();
difference = now - start;
if (difference > ms) {
break;
}
}
}
const goShopping = (list, cbItemReport, cbFinished, cbError) => {
let count = 0;
let numberFound = 0;
const randomError = Math.floor(Math.random() * 3);
if (randomError == 0) {
cbError('Something went wrong, trip aborted.');
} else {
list.forEach(item => {
const randomFound = Math.floor(Math.random() * 4);
if (randomFound > 0) {
cbItemReport(item, true, ++count);
numberFound++;
} else {
cbItemReport(item, false, ++count);
}
sleep(1000);
})
cbFinished(`Bought ${numberFound} things.`);
}
}
goShopping(['milk', 'eggs', 'sugar', 'bread'],
(item, found, count) => {
console.log(`Item #${count} "${item}" was ${found ? 'found' : 'not found'}.`);
},
(message) => {
console.log("Returned from shopping: " + message);
},
(error) => {
console.log("ERROR: " + error);
});
sleep=function(毫秒){
var start=new Date().getTime();
现在设=0;
设差=0;
对于(变量i=0;i<1e17;i++){
现在=新日期().getTime();
差异=现在-开始;
如果(差异>毫秒){
打破
}
}
}
const goShopping=(列表、cbItemReport、cbFinished、cbError)=>{
让计数=0;
设numberFound=0;
const randomError=Math.floor(Math.random()*3);
如果(随机错误==0){
cbError('发生故障,跳闸中止');
}否则{
list.forEach(项=>{
const randomFound=Math.floor(Math.random()*4);
如果(发现的随机数>0){
cbItemReport(项,真,++计数);
numberFound++;
}否则{
cbItemReport(项,假,++计数);
}
睡眠(1000);
})
cbFinished(`bunded${numberFound}things.`);
}
}
goShopping([‘牛奶’、‘鸡蛋’、‘糖’、‘面包’),
(项目、找到、计数)=>{
log(`Item#${count}${Item}是${found?'found':'notfound}.`);
},
(信息)=>{
console.log(“购物返回:+消息”);
},
(错误)=>{
日志(“错误:+错误”);
});
我将如何将后面使用的回调转换为承诺?在这种情况下,三个回调
cbItemReport
、cbFinished
、cbError
太多,无法映射到Promise拥有的两个回调,即仅resolve
(cbFinished)和reject
(cbError),或者我缺少什么?从cbFinished
调用resolve
,从cbError
中拒绝
,并编写一个cbItemReport
,它可以对每个项目执行您希望它执行的操作,就像在现有代码中一样。从它听起来的样子来看,您希望实现类似于RxJs库的功能,那么为什么不直接使用它呢
查看RxJs
例如,一个呼叫可能如下所示:
const sub = new Subject(); // Create a subject
sub.asObservable().subscribe( // Subscribe to that subject as obserable
({item, found, count}) => { // next
console.log(`Item #${count} "${item}" was ${found ? 'found' : 'not found'}.`);
},
error => { // error
console.log("ERROR: " + error);
},
message => { // complete
console.log("Returned from shopping: " + message);
}
);
const goShopping = (list) => {
let count = 0;
let numberFound = 0;
const randomError = Math.floor(Math.random() * 3);
if (randomError == 0) {
sub.error('Something went wrong, trip aborted.'); // push an error to the subject
} else {
list.forEach(item => {
const randomFound = Math.floor(Math.random() * 4);
if (randomFound > 0) {
sub.next({item: item, found: true, count: ++count}); // push a result to subject (single object)
numberFound++;
} else {
sub.next({item: item, found: true, count: ++count}); // same as above
}
sleep(1000);
})
sub.complete(`Bought ${numberFound} things.`); // push complete to subject. after that no next is allowed anymore
}
}
goShopping(['milk', 'eggs', 'sugar', 'bread'])