Javascript 如何结合来自不同承诺的论点?

Javascript 如何结合来自不同承诺的论点?,javascript,promise,Javascript,Promise,这个问题应该很清楚:我想使用如下语句写入日志文件。您可以假设此语句位于按钮的单击处理程序中。这个伪代码中包含两个问题 pLogInfo("local info").then(pauseUntilSettled).catch(err); // This is my goal 以下是我的库函数(每个函数都返回一个承诺): 用法: pLogInfo("local info").then(pauseUntilSettled).catch(err); function pauseUntilSettle

这个问题应该很清楚:我想使用如下语句写入日志文件。您可以假设此语句位于按钮的单击处理程序中。这个伪代码中包含两个问题

pLogInfo("local info").then(pauseUntilSettled).catch(err); // This is my goal
以下是我的库函数(每个函数都返回一个承诺):

用法:

pLogInfo("local info").then(pauseUntilSettled).catch(err);

function pauseUntilSettled()
    {
    // How to wait before returning from
    // the button click event handler?
    } // pauseUntilSettled
19年8月27日增补:

对于这个常见问题,我想到了几种可能的解决方案:

  • 将对象附加到链中的一个顶级函数(p.data={})。您可以将任何参数或回调存储在对象中,并在任何异步“then”代码中引用它们。这是因为作为对象父对象的函数具有全局作用域。如果在现有承诺尚未解决时触发同一线程的另一个顶级承诺,则可能会失败,因为新的执行线程将共享并覆盖该对象。我已经成功地使用了这种方法,这是上述全球公式的一种变体,但它显然是不安全的

  • 创建一个闭包函数来传播异步线程。闭包函数包含其参数和引用的全局变量的快照。我还没有得到这个想法的工作,但它似乎是合理的

  • 创建一个新的Promise,作为Promises线程的一部分或作为一个单独的助手,该Promise使用一个对象而不是单个值调用其resolve函数。使用该对象向每个“then”函数传播多个值。我也没有让这个想法起作用


  • 我希望这些想法能激励一些人(包括我自己)想出一个解决方案,因为这是一个非常常见的问题,不常被讨论。

    Satpal为承诺提供了一个很好的答案。另一种选择是使用RXJS库,并利用构建在承诺之上的可观察性。它们有一个next()、error()和complete()块,其中代码只会在流中接收到值后执行。如果要等待多个服务响应,可以通过多种方式将流组合在一起


    我知道这不是你想要的确切答案,但它是一个非常有用的库。这是文件

    Satpal给了承诺一个很好的回答。另一种选择是使用RXJS库,并利用构建在承诺之上的可观察性。它们有一个next()、error()和complete()块,其中代码只会在流中接收到值后执行。如果要等待多个服务响应,可以通过多种方式将流组合在一起

    我知道这不是你想要的确切答案,但它是一个非常有用的库。这是文件

    解决方案:

    您可以使用“bind”将中间值显式地放入任何稍后的“then”函数的作用域中。这是一个很好的解决方案,它不需要更改承诺的工作方式,只需要一两行代码来传播值,就像传播错误一样

    下面是一个完整的示例:

    // Get info asynchronously from a server
    function pGetServerInfo()
        {
        // then value: "server info"
        } // pGetServerInfo
    
    // Write into a file asynchronously
    function pWriteFile(path,string)
        {
        // no then value
        } // pWriteFile
    
    // The heart of the solution: Write formatted info into a log file asynchronously,
    // using the pGetServerInfo and pWriteFile operations
    function pLogInfo(localInfo)
        {
        var scope={localInfo:localInfo}; // Create an explicit scope object
        var thenFunc=p2.bind(scope); // Create a temporary function with this scope
        return (pGetServerInfo().then(thenFunc)); // Do the next 'then' in the chain
        } // pLogInfo
    
    // Scope of this 'then' function is {localInfo:localInfo}
    function p2(serverInfo)
        {
        // Do the final 'then' in the chain: Writes "local info, server info"
        return pWriteFile('log',this.localInfo+','+serverInfo);
        } // p2
    
    可以按如下方式调用此解决方案:

    pLogInfo("local info").then().catch(err);
    
    (注意:此解决方案的一个更复杂、更完整的版本已经过测试,但此示例版本尚未测试,因此可能会出现编写的错误。)

    解决方案:

    您可以使用“bind”将中间值显式地放入任何稍后的“then”函数的作用域中。这是一个很好的解决方案,它不需要更改承诺的工作方式,只需要一两行代码来传播值,就像传播错误一样

    下面是一个完整的示例:

    // Get info asynchronously from a server
    function pGetServerInfo()
        {
        // then value: "server info"
        } // pGetServerInfo
    
    // Write into a file asynchronously
    function pWriteFile(path,string)
        {
        // no then value
        } // pWriteFile
    
    // The heart of the solution: Write formatted info into a log file asynchronously,
    // using the pGetServerInfo and pWriteFile operations
    function pLogInfo(localInfo)
        {
        var scope={localInfo:localInfo}; // Create an explicit scope object
        var thenFunc=p2.bind(scope); // Create a temporary function with this scope
        return (pGetServerInfo().then(thenFunc)); // Do the next 'then' in the chain
        } // pLogInfo
    
    // Scope of this 'then' function is {localInfo:localInfo}
    function p2(serverInfo)
        {
        // Do the final 'then' in the chain: Writes "local info, server info"
        return pWriteFile('log',this.localInfo+','+serverInfo);
        } // p2
    
    可以按如下方式调用此解决方案:

    pLogInfo("local info").then().catch(err);
    

    (注意:此解决方案的一个更复杂、更完整的版本已经过测试,但不是此示例版本,因此可能会有编写的错误。)

    看起来很有趣:通过等待特定值准备就绪来编写函数(函数编程)。这在某些情况下很有用。我认为,在实际编程中并不多。从我的观点来看,wtih RxJS的大问题与承诺是一样的:它都基于回调、隔离闭包,这对于大多数共享名称空间(至少在本地共享名称空间)的编程来说是过分的。JavaScript中新的异步特性仍然表示单独的回调,即使是连续编写的。依我看,JavaScript需要被一种没有消息处理循环的语言所取代。看起来很有趣:通过等待特定值准备就绪来编写函数(函数编程)。这在某些情况下很有用。我认为,在实际编程中并不多。从我的观点来看,wtih RxJS的大问题与承诺是一样的:它都基于回调、隔离闭包,这对于大多数共享名称空间(至少在本地共享名称空间)的编程来说是过分的。JavaScript中新的异步特性仍然表示单独的回调,即使是连续编写的。JavaScript需要被一种没有消息处理循环的语言所取代,IMO。