繁体   English   中英

"链接回调的最佳方式?"

[英]Best Way to Chain Callbacks?

我有一个关于在它们之间传递数据时将回调链接在一起的最佳方法的问题。 我在下面有一个有效的示例,但有一个缺陷是函数必须知道链并知道它们的位置/是否传递回调。

function first(data, cb1, cb2, cb3){
    console.log("first()", data);
    cb1(data,cb2, cb3);
}
function second(data, cb1, cb2) {
    console.log("second()",data);
    cb1(data, cb2);
}
function third(data, cb) {
    console.log("third()",data);
    cb(data);
}
function last(data) {
    console.log("last() ", data);
}
first("THEDATA", second, third, last);  // This work OK
first("THEDATA2", second, last);        // This works OK
first("THEDATA3", second);              // This doesn't work as second tries to pass on a callback that doesn't exit.

我可以想出很多方法来解决这个问题,但它们都涉及让被调用的函数知道正在发生的事情。 但我的问题是我正在处理的真正功能已经存在,如果可以避免的话,我不想修改它们。 所以我想知道我是否错过了如何调用这些的技巧?

感谢您的回答,我同意 promise 可能是最合适的解决方案,因为它们满足我的要求并提供许多其他优势。

但是,我也想出了如何在不涉及任何额外模块的情况下做我想做的事情。

回顾一下具体的要求是:

  • 通过回调将多个函数链接在一起(这样第一个函数可以使用其他函数依赖的非阻塞 I/O 调用),
  • 在它们之间传递参数(数据)时,以及
  • 无需修改现有函数以了解它们在回调链中的位置。

我缺少的“技巧”是引入一些额外的匿名回调函数来充当现有函数之间的链接。

// The series of functions now follow the same pattern, which is how they were before
// p1 data object and p2 is a callback, except for last().
function first(data, cb){
    console.log("first()", data);
    cb(data);
}
function second(data, cb) {
    console.log("second()",data);
    cb(data);
}
function third(data, cb) {
    console.log("third()",data);
    cb(data);
}
function last(data) {
    console.log("last() ", data);
}

// And the named functions can be called pretty much in any order without 
// the called functions knowing or caring. 

// first() + last()
first("THEDATA", function (data) { // The anonymous function is called-back, receives the data, 
    last(data);                    // and calls the next function.
});

// first() + second() + last()
first("THEDATA2", function (data) {
    second(data, function (data){
        last(data);
    }); // end second();
}); // end first();

// first() + third()! + second()! + last()
first("THEDATA3", function (data) {
    third(data, function (data){
        second(data, function (data){
            last(data);
        }); // end third();
    }); // end second();
}); // end first();

Promise 是可行的方法,因为它们提供以下好处:

  • 顺序回调链
  • 并行回调链(种类)
  • 异常处理
  • 轻松绕过物体

通常,一个Promise执行一些操作,然后将自己的状态更改为被rejected - 失败,或者resolved了它已完成并且我们有结果。 现在,每个承诺都有方法then(function(result), function(error)) 这个then()方法在Promiseresolved或被rejected 如果已解决,则执行then()的第一个参数,并带有结果,如果 Promise 被拒绝,则执行第二个参数。

一个典型的回调链看起来像:

示例 1:

someMethodThatReturnsPromise()
 .then(function (result) {
  // executed after the someMethodThatReturnsPromise() resolves
  return somePromise;
 }).then(function (result) {
  // executed after somePromise resolved 
 }).then(null, function (e) {
  // executed if any of the promise is rejected in the above chain
 });

你首先如何创建一个Promise 你这样做:

new Promise (function (resolve, reject) {
   // do some operation and when it completes
   resolve(result /*result you want to pass to "then" method*/)
   // if something wrong happens call "reject(error /*error object*/)"
});

欲了解更多详情:前往这里

最佳做法是检查您正在调用的回调是否在 args 中提供。

function first(data, cb1, cb2, cb3){
    console.log("first()", data); // return something
    if(cb1){
        cb1(data,cb2, cb3);
    }
}
function second(data, cb1, cb2) {
    console.log("second()",data); // return something
    if(cb1){
        cb1(data, cb2);
    }
}
function third(data, cb) {
    console.log("third()",data); // return something
    if(cb){
        cb(data);
    }
}
function last(data) {
    console.log("last() ", data); // return something
}
first("THEDATA", second, third, last);  // This work OK
first("THEDATA2", second, last);        // This works OK
first("THEDATA3", second);

这将正常工作。 或者,还有更多选项,例如 Promises 和 Async library e.tc

也许你想这样尝试,是的,使用“Promise”有更多功能,但是如果你想要更简单的东西,我们可以这样做,是的,这是没有错误检查的,但是我们当然可以使用 try / catch

 function Bersambung(cb){ this.mainfun = cb this.Lanjut = function(cb){ var thisss = this; if(cb){ return new Bersambung(function(lanjut){ thisss.mainfun(function(){ cb(lanjut); }) }) } else { this.mainfun(function(){}); } } } //You can use it like this : var data1 = "", data2 = "" , data3 = "" new Bersambung(function(next){ console.log("sebelum async") setTimeout(function(){ data1 = "MENYIMPAN DATA : save data" next(); },1000); }).Lanjut(function(next){ if(data1 == ""){ return; // break the chain } console.log("sebelum async 2") setTimeout(function(){ console.log("after async") console.log(data1); next(); },1000) }).Lanjut();

好的,这可能并不理想,但它确实有效。<\/code>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM