How to use Vital.Async.Promise

Couple months ago, on the new year’s day 2018-01-01, Dog a.k.a. linda_pp or rhysd created a vital.vim module Async.Promise.

INTRODUCTION Vital.Async.Promise-introduction

Vital.Async.Promise is a library to represent the eventual completion or
failure of an asynchronous operation. APIs are aligned to ES6 Promise. If you
already know them, you can start to use this library easily.

Instead of callbacks, Promise provides:

  • a guarantee that all operations are asynchronous. Functions given to .then()
    method or .catch() method is executed on next tick (or later) using
    |timer_start()|.
  • chaining asynchronous operations. Chained operation’s order is sequentially
    run and the order is guaranteed.
  • persistent error handling using .catch() method. Please be careful of
    floating Promise. All Promise should have .catch() call not to squash an
    exception.
  • flow control such as awaiting all Promise objects completed or selecting
    the fastest one of Promises objects.

If you know the detail of APIs, documents for ES6 Promise at Mozilla Developer
Network and ECMA-262 specs would be great.

Mozilla Developer Network:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

ECMA-262:
https://www.ecma-international.org/publications/standards/Ecma-262.htm

https://github.com/vim-jp/vital.vim/blob/master/doc/vital/Async/Promise.txt

As the introduction mentioned, it is an ES6 Promise compatible interface for Vim scripts. You can use it as a fully controllable abstract layer on lowest layer Vim functions job_start/timer_start or vimproc.vim for your plugin developments.

Trivial example: echo message after a while

Let’s implement something like this without blocking Vim.

sleep 5 " This is blocking. We don't want to use `:sleep`
echo 'it has been 5 seconds'

Back then we don’t have timer_start Vim script function, we had to register events such as CursorHold or CursorHoldI to check what time is it and compare with a base you prepared.

Now we have Vim native function timer_start(), so let’s use it first without vital.

function! s:my_echo(timer_id) abort
echo 'it has been 5 seconds'
endfunction

echo timer_start(5000, function('s:my_echo'))

It works. When you evaluate them your Vim won’t block you; you can do anything. And after 5 seconds you get the message shown.

You can shorten that with using Vim8 lambda. The below and the above are conceptually same.

echo timer_start(5000, {_ ->
\ execute('echo "it has been 5 seconds"', '')
\})

Let’s use Vital.Async.Promise this time.

let s:P = vital#vital#import('Async.Promise')

call s:P.new({resolve -> timer_start(5000, resolve)})
\.then({->
\ execute('echo "it has been 5 seconds"', '')
\})

They look quite similar so far.

Let’s continue into a little bit more complicated example.

Example: fault tolerant chained operations with job_start/channel

Coming soon…

Advertisements

How to use vimrepress

Assuming you already have neobundle installed, and you are using Gentoo Linux.

vimrepress: https://github.com/iyf/vimrepress

  1. make sure youf vim has python USE flag
  2. emerge dev-python/markdown
  3. make ~/.vimpressrc with referring the github repo
  4. install vimrepress

    if has('python')
      NeoBundle 'iyf/vimrepress'
    endif
  5. :BlogNew to create a new buffer for start writing a blog post in markdown

  6. :BlogSave publish to post the data and release it

You can also refer the list of blog post to edit by :BlogList

Added on 2015-04-25: this failed with error now and I can no longer use this for some reason.