简体   繁体   English

Javascript和回调和deferred。 如何在google gmail API请求完成后运行某个功能?

[英]Javascript and callbacks and defered. How can I run a function after a google gmail API request completes?

I have built up a javascript file that starts with: 我已经构建了一个以以下内容开头的javascript文件:

var myApp = function () {

var CLIENT_ID = 'xxxxxxx';
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];
var SCOPES = 'https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/analytics.readonly https://www.googleapis.com/auth/drive.readonly';
var authorizeButton = document.getElementById('authorize-button');

return {

The functions are declared like: 这些函数声明如下:

    getSent: function(callback) {
    var request = gapi.client.gmail.users.messages.list({
      'userId': 'me',
      'labelIds': 'SENT',
      'maxResults': 10
    });

    request.execute(function(response) {
      $.each(response.messages, function() {
        var messageRequest = gapi.client.gmail.users.messages.get({
          'userId': 'me',
          'id': this.id
        });


        messageRequest.execute(myApp.appendMessageRow);
      });
    });
  },

And then run through a single function that calls others: 然后运行一个调用其他函数的函数:

myApp.init();

How can I defer a function to be run after my google request function getsent() has been fully completed. 在谷歌请求函数getsent()完全完成后,如何推迟运行函数。 I have tried using callbacks to another function and it runs but it runs while the getsent() is still being executed. 我已经尝试将回调用于另一个函数并且它运行但是当getsent()仍在执行时它会运行。 Can I use the jQuery method defered to run the callback when done? 完成后我可以使用jQuery方法来运行回调吗?

I have tried: myApp.getSent(myApp.gMailSyncComplete()); 我试过了:myApp.getSent(myApp.gMailSyncComplete()); // Runs early //尽早运行

and I tried: myApp.getSent().done(myApp.gMailSyncComplete()); 我尝试过:myApp.getSent()。done(myApp.gMailSyncComplete()); // no jQuery done defined //没有定义jQuery

Some important errors in your code: 代码中的一些重要错误:

  • You are creating a function getSent that accepts a callback, but you are not calling the callback at all so it won't get executed ever. 您正在创建一个接受回调的函数getSent ,但您根本不会调用回调,因此它不会被执行。 You should execute the callback when everything else is done. 当其他一切都完成后,你应该执行回调。
  • You are not waiting for all message requests to be completed. 您不是在等待所有消息请求完成。 You can use a library like async which has the method map to be able to execute all requests in parallel and wait for all of them to be completed before calling the callback. 您可以使用像async这样的库,它具有方法映射 ,能够并行执行所有请求,并在调用回调之前等待所有请求完成。

With these two things in mind, and using async , this would be an example of the resulting code: 考虑到这两件事,并使用async ,这将是结果代码的一个示例:

getSent: function (callback) {
  var request = gapi.client.gmail.users.messages.list({
    'userId': 'me',
    'labelIds': 'SENT',
    'maxResults': 10
  })

  request.execute(function (response) {
    async.map(response.messages, function (msg, cb) {
        var messageRequest = gapi.client.gmail.users.messages.get({
          'userId': 'me',
          'id': msg.id
        })

        messageRequest.execute(function (result) {
            myApp.appendMessageRow(result)
            cb()
        })
    }, function (err) {
      if (err) throw err
      callback()
    })
  })
}
  • Lastly, when invoking this function, keep in mind that the callback parameter must be a function. 最后,在调用此函数时,请记住callback参数必须是函数。

To make things clear, let's translate the code you wrote, myApp.getSent(myApp.gMailSyncComplete()) , into an equivalent structure: 为了清楚myApp.getSent(myApp.gMailSyncComplete()) ,让我们将您编写的代码myApp.getSent(myApp.gMailSyncComplete())转换为等效结构:

var callback = myApp.gMailSyncComplete()
myApp.getSent(callback)

When you do this, you are not passing the function but the result of the function , because you are executing it. 执行此操作时,您没有传递函数,而是传递函数 的结果 ,因为您正在执行它。 That's why it gets executed immediately. 这就是它立即执行的原因。 The correct way to do this would be the following: 正确的方法是:

var callback = myApp.gMailSyncComplete
myApp.getSent(callback)

Or, in your one-liner example, myApp.getSent(myApp.gMailSyncComplete) 或者,在您的单行示例中, myApp.getSent(myApp.gMailSyncComplete)

you can use javascript promise. 你可以使用javascript承诺。

    function testPromise() {  
    let p1 = new Promise(
        // The resolver function is called with the ability to resolve or
        // reject the promise
       (resolve, reject) => {
            /*your async function*/  
      }
    );
  // defined what to do when the promise is resolved with the then() call,
    // and what to do when the promise is rejected with the catch() call
    p1.then(
        // Log the fulfillment value
        function(val) {
            log.insertAdjacentHTML('beforeend', val +
                ') Promise fulfilled (<small>Async code terminated</small>)<br/>');
        })
    .catch(
        // Log the rejection reason
       (reason) => {
            console.log('Handle rejected promise ('+reason+') here.');
        });
}

You could use jQuery promise() , check the example below. 你可以使用jQuery promise() ,查看下面的例子。

getSent: function() {
var request = gapi.client.gmail.users.messages.list({
  'userId': 'me',
  'labelIds': 'SENT',
  'maxResults': 10
});

request.execute(function(response) {
  $.each(response.messages, function() {
    var messageRequest = gapi.client.gmail.users.messages.get({
      'userId': 'me',
      'id': this.id
    });


    messageRequest.execute(myApp.appendMessageRow);
  });
});
},
...
$.when( myApp.getSent() ).done(function() {
    // do whatever you want in here as callback
});

Inside of your getSent function create a jQuery Deferred object and return a promise. 在你的getSent函数内部创建一个jQuery Deferred对象并返回一个promise。 Then after request.execute has finished you can call resolve/reject. 然后在request.execute完成后,您可以调用resolve / reject。 I created a small snippet to show example. 我创建了一个小片段来展示示例。 Maybe you can modify to fit your needs 也许你可以修改以满足你的需求

 $(document).ready(function () { var i =0; function getText() { var deferred = $.Deferred(); setTimeout(function () { i++; deferred.resolve("text " + i); }, 3000); return deferred.promise(); } getText().then(function (value) { console.log(value); }).then(function () { getText().then(function (value2) { console.log(value2); }); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

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

相关问题 AJAX请求完成后,如何调用PartialView中定义的JavaScript函数? - How can I call a JavaScript function defined in a PartialView after an AJAX request completes? Bootstrap完成功能后,如何在jQuery中运行功能? - How do I run a function in jQuery after Bootstrap completes a function? Google Loader运行后,我可以运行JavaScript函数吗? - Can I run a JavaScript function AFTER Google Loader has run? 在所有回调完成后,如何处理多个 Google Places API 结果? - How can I process multiple Google Places API results after all the callbacks have completed? 如何在另一个完成后运行功能 - how to run function after another one completes 仅在Angular中发出$ http请求后,才能运行javascript函数? - How can I run a javascript function only after a $http request has been made in Angular? 在AJAX请求完成后调用PartialView中定义的JavaScript函数吗? - Calling JavaScript function defined in a PartialView after AJAX request completes? 在另一个函数完成JavaScript和JQuery之后运行函数 - Run function after another function completes JavaScript and JQuery 仅在第一个功能完全完成后如何运行第二个Javascript功能? - How to run second Javascript function only after first function fully completes? 如何从PHP函数运行JavaScript AJAX请求? - How can I run a JavaScript AJAX request from a PHP function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM