简体   繁体   English

无法保证可以使用外部功能

[英]Can't get promise to work with external function

I'm trying to wrap my head around the javascript promises since I need them in a project I'm working on. 由于我在一个正在进行的项目中需要它们,因此我想把头放在javascript Promise上。 I've tried several things but never got it to work. 我已经尝试了几件事,但从未成功。

Here's the problem: 这是问题所在:

I have a function that connects to a server via websockets, grabs certain infos and delivers them as an object. 我有一个功能,可以通过websockets连接到服务器,获取某些信息并将其作为对象传递。 As this is async, I need to wait until this process has finished to go on with the infos I got. 由于这是异步的,因此我需要等到此过程完成后再继续处理我得到的信息。

This is the global function for getting the infos: 这是获取信息的全局功能:

function getInfos(par1, par2) {

    // Open Websocket connection, ask for infos and wait for Answer/Message.

    OnMessage: function (aEvent, aToken) {
        if (aToken == "JustAString") {

            // Does this work this way? I need to get the "aToken" to the "MyCalltoServer" Function that called this mess here
            return aToken;

           // Tried this to resolve the promise created in the other script.
            resolve(MyCallToServer);
        }
    }
}

This is how I tried to create a promise with my existing getInfos function. 这就是我尝试使用现有的getInfos函数创建一个Promise的方式。

var promiseResolve, promiseReject;

var MyCallToServer = new Promise(function(resolve, reject){

promiseResolve = resolve;
promiseReject = reject;

getInfos(par1,par2);


});

MyCallToServer.then(function(){
    console.log("done");
    console.log(aToken);
})

Long story short - it doesn't work at all. 长话短说-根本不起作用。 Any help is greatly appreciated. 任何帮助是极大的赞赏。 The thing is I can't change the construction of the getInfos function since it's way to complex already (300 cases for different answers). 关键是我无法更改getInfos函数的构造,因为它已经很复杂了(300个案例用于不同的答案)。 So I thought maybe there's a way to include the promise resolving in it? 所以我想也许有一种方法可以将承诺解决方案纳入其中?

Any Help is greatly appreciated !!! 任何帮助是极大的赞赏 !!!

Not certain why OnMessage is within getInfos or why the syntax is 不能确定为什么OnMessage是内getInfos为什么语法

OnMessage: function (aEvent, aToken) {}

You can return a Promise from getInfos() call, pass aToken to resolve() , include error handling function passed to .catch() 您可以从getInfos()调用返回Promise ,将aToken传递给resolve() ,包括传递给.catch()错误处理函数。

function getInfos(par1, par2) {

  // Open Websocket connection, ask for infos and wait for Answer/Message.
  return new Promise(function(resolve, reject) {
    function OnMessage(aEvent, aToken) {
        if (aToken == "JustAString") {
            resolve(aToken);
        }
    };
    OnMessage()
  })
}

function MyCallToServer(par1, par1) {
  return getInfos(par1, par2)
}

function handleMyCallToServer(aToken) {
  console.log("done");
  console.log(aToken);
}

function handleMyCallToServerErroir(err) {
  console.log("error");
  console.err(err);
}

MyCallToServer(1, 2)
.then(handleMyCallToServer)
.catch(handleMyCallToServerError)

Promises can't be reused. 承诺不能重用。 Creating a global promise variable to be resolved/rejected from a parameterized function that can be called multiple times is tantamount to setting up non-reentrant, asynchronous code. 创建一个可以被多次调用的参数化函数解析/拒绝的全局promise变量,等同于设置不可重入的异步代码。 Do not go there. 不要去那边。

A classic way to provide asynchronous data is to use a call back function taking two parameters, one of which is set according to the final result of the operation: 提供异步数据的经典方法是使用带有两个参数的回调函数,其中一个参数根据操作的最终结果进行设置:

 function getInfos( par1, par2, callBack) {

     //  in asynchronous code that successfully delivers dataObject 

          callBack( false, dataObject); // valid data
          return; // from asynchronous service code

     //  in asynchronous code that detected an error

          callBack( error) // no valid data
          return; // from asynchronous service code

  }

which is called with a callback function patterned on: 通过以下方式调用的回调函数进行调用:

  function callBack( err, data) {
      if( err) {
      //   the bad news
      }
      if( data) {
      // the good news.
      }
  }

Alternatively you can promisify getInfos by returning a pending promise that is resolved or rejected after network operations have taken place. 或者,您可以通过返回在网络操作发生后已解决或被拒绝的未决承诺来使getInfos getInfos This can be achieved by placing all the code (for getInfos ) in an ES6 promise executor function which is called synchronously during promise construction: 这可以通过将所有代码(用于getInfos )放在ES6 getInfos执行程序函数中来实现,该函数在getInfos构建期间被同步调用:

function getInfos( par1, par2) {
    return new Promise( function(resolve, reject) {
        // initiate getInfos things with supplied par1, par2 values

        // in asynchronous code that successfully created dataObject

             resolve( dataObject);
             return; // from asynchronous service code

        // in asynchronous code that failed
             reject( new Error( "error text");
             return; // from asynchronous service code
    });
}

Some libraries provide both mechanisms by always returning a promise (which need not be used) besides conditionally calling a callback if one is provided. 有些库通过始终返回一个promise(不需要使用)来提供这两种机制,此外,如果有条件的话,有条件地调用回调。 I would suggest simply promisifying getInfos in this case. 在这种情况下,我建议简单地散布getInfos


Edit. 编辑。 The code in comment replicates a JQuery "deferred" object with a variety of deconstructed promise object components and variables. 注释中的代码复制了带有各种解构的Promise对象组件和变量的JQuery“延迟”对象。 This is a kludge I do not recommend pursuing. 我不建议这样做。

A simpler solution is to first modify getInfos to return a promise then replace 一个更简单的解决方案是先修改getInfos以返回诺言,然后替换

 $(document).ready(function() { var promiseResolve, promiseReject; var FunctionThatCallsServerFunction = new Promise(function(resolve, reject) { promiseResolve = resolve; promiseReject = reject; getInfos(par1,par2); }); FunctionThatCallsServerFunction.then(function() { console.log("done"); // aToken should be received from the ServerFunction console.log(aToken); }) }) 

with

 $(document).ready( function() { getInfos( par1, par2) .then(function( aToken) { console.log("done"); console.log(aToken); }) .catch( function( err) { console.log("An error occurred: "); console.log( err); }); }) 

which uses the promise returned by getInfos directly. 它直接使用getInfos返回的getInfos Notice that 注意

  • the value used to fulfill a promise is passed as the argument value to a fulfillment handler supplied with .then , and 用于实现承诺的值作为参数值传递给.then随附的实现处理程序,并且
  • generally include a catch clause to avoid "unhandled promise rejection" exceptions being thrown by Promise software in the event of an error. 通常包括catch子句,以避免在发生错误时Promise软件引发“未处理的诺言拒绝”异常。

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

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